Azure NoSQL In ASP.NET Core 2.0

Problem

How to use Azure NoSQL database in ASP.NET Core.

Solution

Create a class library and add NuGet package Microsoft.Azure.DocumentDB.Core.

Add a class to encapsulate settings,

  1. public class AzureNoSqlSettings  
  2.     {  
  3.         public AzureNoSqlSettings(string endpoint, string authKey,  
  4.                                   string databaseId, string collectionId)  
  5.         {  
  6.             if (string.IsNullOrEmpty(endpoint))  
  7.                 throw new ArgumentNullException("Endpoint");  
  8.    
  9.             if (string.IsNullOrEmpty(authKey))  
  10.                 throw new ArgumentNullException("AuthKey");  
  11.    
  12.             if (string.IsNullOrEmpty(databaseId))  
  13.                 throw new ArgumentNullException("DatabaseId");  
  14.    
  15.             if (string.IsNullOrEmpty(collectionId))  
  16.                 throw new ArgumentNullException("CollectionId");  
  17.    
  18.             this.Endpoint = endpoint;  
  19.             this.AuthKey = authKey;  
  20.             this.DatabaseId = databaseId;  
  21.             this.CollectionId = collectionId;  
  22.         }  
  23.    
  24.         public string Endpoint { get; }  
  25.         public string AuthKey { get; }  
  26.         public string DatabaseId { get; }  
  27.         public string CollectionId { get; }  
  28.     }  

Add a class for repository, which will work with a generic type. Add a constructor and private methods to initialize the Azure client,

  1. public AzureNoSqlRepository(AzureNoSqlSettings settings)  
  2.         {  
  3.             this.settings = settings ?? throw new ArgumentNullException("Settings");  
  4.             Init();  
  5.         }  
  6.         private AzureNoSqlSettings settings;  
  7.         private DocumentClient client;  
  8.    
  9.         private void Init()  
  10.         {  
  11.             client = new DocumentClient(  
  12. new Uri(this.settings.Endpoint), this.settings.AuthKey);  
  13.             CreateDatabaseIfNotExistsAsync().Wait();  
  14.             CreateCollectionIfNotExistsAsync().Wait();  
  15.         }  
  16.    
  17.         private async Task CreateDatabaseIfNotExistsAsync()  
  18.         {  
  19.             await client.ReadDatabaseAsync(  
  20. UriFactory.CreateDatabaseUri(this.settings.DatabaseId));  
  21.         }  
  22.    
  23.         private async Task CreateCollectionIfNotExistsAsync()  
  24.         {  
  25.             await client.ReadDocumentCollectionAsync(  
  26.                     UriFactory.CreateDocumentCollectionUri(  
  27. this.settings.DatabaseId, this.settings.CollectionId));  
  28.         }  

Add methods to get one or more items,

  1. private Uri GetCollectionUri()  
  2.         {  
  3.             return UriFactory.CreateDocumentCollectionUri(  
  4.                    this.settings.DatabaseId, this.settings.CollectionId);  
  5.         }  
  6.    
  7.         private Uri GetDocumentUri(string documentId)  
  8.         {  
  9.             return UriFactory.CreateDocumentUri(  
  10.                    this.settings.DatabaseId, this.settings.CollectionId, documentId);  
  11.         }  

Now add public methods for the repository,

  1. public async Task<List<T>> GetList()  
  2.         {  
  3.             var query = this.client  
  4.                             .CreateDocumentQuery<T>(GetCollectionUri())  
  5.                             .AsDocumentQuery();  
  6.    
  7.             var results = new List<T>();  
  8.             while (query.HasMoreResults)  
  9.             {  
  10.                 results.AddRange(await query.ExecuteNextAsync<T>());  
  11.             }  
  12.    
  13.             return results;  
  14.         }  
  15.         public async Task<T> GetItem(string id)  
  16.         {  
  17.             Document document = await this.client.ReadDocumentAsync(  
  18. GetDocumentUri(id));  
  19.             return (T)(dynamic)document;  
  20.         }  
  21.    
  22.         public async Task<Document> Insert(T item)  
  23.         {  
  24.             return await this.client.CreateDocumentAsync(GetCollectionUri(), item);  
  25.         }  
  26.    
  27.         public async Task<Document> Update(string id, T item)  
  28.         {  
  29.             return await this.client.ReplaceDocumentAsync(GetDocumentUri(id), item);  
  30.         }  
  31.    
  32.         public async Task<Document> InsertOrUpdate(T item)  
  33.         {  
  34.             return await this.client.UpsertDocumentAsync(GetCollectionUri(), item);  
  35.         }  
  36.    
  37.         public async Task Delete(string id)  
  38.         {  
  39.             await this.client.DeleteDocumentAsync(GetDocumentUri(id));  
  40.         }  

Inject and use repository,

  1. public class MovieService : IMovieService  
  2.     {  
  3.         private readonly IAzureNoSqlRepository<Movie> repository;  
  4.    
  5.         public MovieService(IAzureNoSqlRepository<Movie> repository)  
  6.         {  
  7.             this.repository = repository;  
  8.         }  

In ASP.NET Core Web Application, configure services,

  1. public void ConfigureServices(  
  2.     IServiceCollection services)  
  3. {  
  4.     services.AddScoped<IAzureNoSqlRepository<Movie>>(factory =>  
  5.     {  
  6.         return new AzureNoSqlRepository<Movie>(  
  7.             new AzureNoSqlSettings(  
  8.                 endpoint: Configuration["NoSql_Endpoint"],  
  9.                 authKey: Configuration["NoSql_AuthKey"],  
  10.                 databaseId: Configuration["NoSql_Database"],  
  11.                 collectionId: Configuration["NoSql_Collection"]));  
  12.     });  
  13.     services.AddScoped<IMovieService, MovieService>();  
  14.   
  15.     services.AddMvc();  
  16. }  

Discussion

The sample code will require you to setup Azure account, NoSQL database and collection. Instructions for these can be found here.

Source Code