Azure Cosmos DB is the Cloud Database for AI Era, its features make it the option for globally and fast access distributed databases: Azure Cosmos DB
In this post we are implementing access from Web Api to Azure Cosmos DB with a Generic Repository. Previously we have set up the resource and filled the containers in the database
The implementation of the library to access the database needs the database name, container, and account data
The Generic Repository is implemented in a base class, the abstract pattern is important to override operations such as logical delete or updates with dependencies
METHOD SOFTWARE ©©
In this post we are implementing access from Web Api to Azure Cosmos DB with a Generic Repository. Previously we have set up the resource and filled the containers in the database
The implementation of the library to access the database needs the database name, container, and account data
public static class CosmosDbConfiguration
{
public static void ConfigureCosmosDb(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<ICosmosUsersLibrary>(InitializeCosmosClientInstanceAsync(configuration.GetSection("CosmosDbUsers")));
}
private static CosmosUsersLibrary InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
{
string databaseName = configurationSection.GetSection("DatabaseName")!.Value!;
string containerName = configurationSection.GetSection("ContainerName")!.Value!;
string account = configurationSection.GetSection("Account")!.Value!;
// If key is not set, assume we're using managed identity
string key = configurationSection.GetSection("Key")!.Value!;
CosmosClient client;
if (string.IsNullOrEmpty(key))
{
ManagedIdentityCredential miCredential = new ();
client = new CosmosClient(account, miCredential);
}
else
{
client = new CosmosClient(account, key);
}
CosmosUsersLibrary cosmosDbService = new (client, databaseName, containerName);
//DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
//await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
return cosmosDbService;
}
}
public class CosmosUsersLibrary(
CosmosClient dbClient,
string databaseName,
string containerName) : CosmosLibrary<CosmosUser>, ICosmosUsersLibrary
{
public override Container Container
{
get
{
return dbClient.GetContainer(databaseName, containerName);
}
}
}
The Generic Repository is implemented in a base class, the abstract pattern is important to override operations such as logical delete or updates with dependencies
using Microsoft.Azure.Cosmos;
namespace Cosmos.Infrastructure;
public abstract class CosmosLibrary<T> : ICosmosLibrary<T> where T : ICosmosItem
{
public abstract Container Container { get; }
public async Task AddItemAsync(T item)
{
await this.Container.CreateItemAsync<T>(item, new PartitionKey(item.Id));
}
public async Task DeleteItemAsync(string id)
{
await this.Container.DeleteItemAsync<CosmosUser>(id, new PartitionKey(id));
}
public async Task<T> GetItemAsync(string id)
{
try
{
ItemResponse<T> response = await this.Container.ReadItemAsync<T>(id, new PartitionKey(id));
return response.Resource;
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return default;
}
}
public async Task<IEnumerable<T>> GetItemsAsync(string queryString)
{
var query = this.Container.GetItemQueryIterator<T>(new QueryDefinition(queryString));
List<T> results = [];
while (query.HasMoreResults)
{
FeedResponse<T> response = await query.ReadNextAsync();
results.AddRange([.. response]);
}
return results;
}
public async Task UpdateItemAsync(string id, T item)
{
await this.Container.UpsertItemAsync<T>(item, new PartitionKey(id));
}
}
METHOD SOFTWARE ©©