Home > OS >  Azure Cosmos DB - How to instantiate Cosmos Db with a different container Id in different controller
Azure Cosmos DB - How to instantiate Cosmos Db with a different container Id in different controller

Time:04-21

I am using .net 6

I am trying to use CosmosDb and I was following this tutorial. The problem is that they are instantiating based only with the container id that is set in appsettings.json

This is how Program.cs

static async Task<CosmosDbService> InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
{
    var databaseName = configurationSection["DatabaseName"];
    var containerName = configurationSection["ContainerName"];
    var account = configurationSection["Account"];
    var key = configurationSection["Key"];
    var client = new CosmosClient(account, key);
    var database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
    await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
    var cosmosDbService = new CosmosDbService(client, databaseName, containerName);
    return cosmosDbService;
}

builder.Services.AddSingleton<ICosmosDbService>(InitializeCosmosClientInstanceAsync(builder.Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult());

And this is how the controller looks like:

namespace demoCosmoDB.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : Controller
    {
        private readonly ICosmosDbService _cosmosDbService;

        public UserController(ICosmosDbService cosmosDbService)
        {
            _cosmosDbService = cosmosDbService ?? throw new ArgumentNullException(nameof(cosmosDbService));
        }
        [HttpGet]
        [Route("{Id:int}")]
        public async Task<IActionResult> GetUser(string Id)
        {
            return Ok(await _cosmosDbService.GetUser(Id));
        }
    }
}

DbService is just an interface on what to implement:

Suppose that I have another controller ArticleController, How can instantiate with the contaienr id e.g "Articles"?

I tried:

static async Task<CosmosClient> InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
{
    var account = configurationSection["Account"];
    var key = configurationSection["Key"];
    var client = new CosmosClient(account, key);
    return client;
}

But I do not know how to modify the rest:

builder.Services.AddSingleton<ICosmosDbService>(InitializeCosmosClientInstanceAsync(builder.Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult()); 
....

CodePudding user response:

Please do not create a client instance per Container. Create a single CosmosClient instance and use it to access any and all Containers in the same account.

For example:

static CosmosClient InitializeCosmosClientInstance(IConfigurationSection configurationSection)
{
    var account = configurationSection["Account"];
    var key = configurationSection["Key"];
    var client = new CosmosClient(account, key);
    return client;
}
builder.Services.AddSingleton<CosmosClient>(InitializeCosmosClientInstance(builder.Configuration.GetSection("CosmosDb")));
namespace demoCosmoDB.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : Controller
    {
        private readonly Container _cosmosContainer;

        public UserController(CosmosClient cosmosClient)
        {
            if (cosmosClient == null) {
                throw new ArgumentNullException(nameof(cosmosClient));
            }

            _cosmosContainer = cosmosClient.GetContainer("dbName", "containerName");
            // you can have different containers for different controllers
        }
        [HttpGet]
        [Route("{Id:int}")]
        public async Task<IActionResult> GetUser(string Id)
        {
           // use the Container to perform your operations
        }
    }
}
  • Related