Author : MD TAREQ HASSAN | Updated : 2020/10/21

Dependency

Nuget packages

Setup

appsettings.json

{

  "CosmosDB": {
    "DBName": "foo_db",
    "DBCollection": "products",
    "DBUri": "https://YOURINSTANCENAME.documents.azure.com:443/",
    "DBKey": "YOUR_KEY"
  }
}

CosmosDBServiceOptions.cs

public class CosmosDBServiceOptions
{
	public string DBUri { get; set; }
	public string DBKey { get; set; }
	public string DBName { get; set; }

	public string DBCollection { get; set; }
}

CosmosDBService.cs

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.Documents.Client;
using Microsoft.Extensions.Options;

namespace Foo.Services
{

    public class CosmosDBService : IDocumentDBService
    {
        DocumentClient docClient;
        string dbName;
		string collectionName; 
        Uri productCollectionUri;

        public CosmosDBService(IOptions<CosmosDBServiceOptions> options, DocumentClient client)
        {
            dbName = options.Value.DBName;
            collectionName = options.Value.DBCollection;

            docClient = client;
            productCollectionUri = UriFactory.CreateDocumentCollectionUri(dbName, collectionName);
        }

        
        // ... ... ...
    }
}

Startup.cs

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Azure.Documents.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace Foo
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {

	        services.AddOptions();

            // Cosmos DB service initialized with config
            IConfiguration dbConfig = Configuration.GetSection(Constants.KEY_DB_CONFIG);
            services.Configure<Services.CosmosDBServiceOptions>(dbConfig);

            // Single doc client for performance
            var docClient = new DocumentClient(new Uri(Configuration[Constants.KEY_COSMOS_URI]), Configuration[Constants.KEY_COSMOS_KEY]);
            services.AddSingleton<DocumentClient>(docClient);

            services.AddScoped<Services.IDocumentDBService, Services.CosmosDBService>();
			
            // ... ... ...
        }

        // ... ... ...
		
    }
}

Create document

namespace Foo.Services
{

    public class CosmosDBService : IDocumentDBService
    {
        // ... ... ...

        public async Task<T> AddProductAsync<T>(T product)
        {
            var dbResponse = await docClient.CreateDocumentAsync(productCollectionUri, product);

            return (dynamic)dbResponse.Resource;
        }

        // ... ... ...
    }
}

Read documents

namespace Foo.Services
{

    public class CosmosDBService : IDocumentDBService
    {
        // ... ... ...
		
        public async Task<List<ProductBase>> GetProductsAsync()
        {
            var productsList =  new List<ProductBase>();

            var products = await docClient.ReadDocumentFeedAsync(productCollectionUri);

            foreach (var item in products)
            {
                productsList.Add((ProductBase)item);
            }

            return productsList;
        }

        // ... ... ...
    }
}

Document details

namespace Foo.Services
{

    public class CosmosDBService : IDocumentDBService
    {
        // ... ... ...
		
        public async Task<ProductBase> GetProductAsync(string id)
        {
            var docUri = UriFactory.CreateDocumentUri(dbName, collectionName, id);

            Document doc = await docClient.ReadDocumentAsync(docUri, new RequestOptions { PartitionKey = new PartitionKey(Undefined.Value) });

            if(doc.GetPropertyValue<string[]> ("Sizes") != null)
            {
                return (FooProduct)(dynamic)doc;
            }
            else
            {
                return (BarProduct)(dynamic)doc;
            }

        }

        // ... ... ...
    }
}

Update document

namespace Foo.Services
{

    public class CosmosDBService : IDocumentDBService
    {
        // ... ... ...
		
        public async Task UpdateProductAsync(string id, string propValue)
        {
            var docUri = UriFactory.CreateDocumentUri(dbName, collectionName, id);

            var docResponse = await docClient.ReadDocumentAsync(docUri, new RequestOptions{ PartitionKey = new PartitionKey(Undefined.Value) });

            var doc = docResponse.Resource;

            doc.SetPropertyValue("prop", propValue);

            await docClient.ReplaceDocumentAsync(doc);
        }

        // ... ... ...
    }
}