Atc.Cosmos 2.0.0

dotnet add package Atc.Cosmos --version 2.0.0
                    
NuGet\Install-Package Atc.Cosmos -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Atc.Cosmos" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Atc.Cosmos" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Atc.Cosmos" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Atc.Cosmos --version 2.0.0
                    
#r "nuget: Atc.Cosmos, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Atc.Cosmos@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Atc.Cosmos&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Atc.Cosmos&version=2.0.0
                    
Install as a Cake Tool

Atc.Cosmos

A .NET library for configuring containers in Azure Cosmos DB and providing an easy way to read and write document resources using System.Text.Json.

NuGet Version NuGet Downloads

Table of Contents

Features

  • Container configuration — declarative setup of Cosmos DB containers with automatic provisioning
  • Read/Write abstractionsICosmosReader<T> and ICosmosWriter<T> for simple CRUD operations
  • Bulk operationsICosmosBulkReader<T> and ICosmosBulkWriter<T> for high-throughput batch operations
  • Change feed processing — built-in change feed processor support with partitioned data handling
  • Paged queries — efficient pagination with continuation token support
  • LINQ queries — query builder support using IQueryable<T>
  • Cross-partition queries — read and query across partition boundaries
  • Optimistic concurrency — ETag-based conflict detection on write operations
  • Update pattern — read-modify-write with automatic retry on conflicts
  • Delete by partition key — bulk delete all documents in a partition
  • Multi-database support — connect to multiple Cosmos DB databases from a single application
  • Unit testing fakesFakeCosmos<T> for testing without a real Cosmos DB instance
  • System.Text.Json — serialization using System.Text.Json with configurable JsonSerializerOptions

Installation

dotnet add package Atc.Cosmos

Getting Started

Once the library is added to your project, you will have access to the following interfaces for reading and writing Cosmos document resources:

Interface Description
ICosmosReader<T> Read Cosmos resources
ICosmosWriter<T> Write Cosmos resources
ICosmosBulkReader<T> Bulk read operations
ICosmosBulkWriter<T> Bulk write operations

A document resource is represented by a class deriving from the CosmosResource base class, or by implementing the ICosmosResource interface directly.

To configure where each resource will be stored in Cosmos, the ConfigureCosmos(builder) extension method is used on the IServiceCollection when setting up dependency injection.

Configure Cosmos Connection

The library uses the CosmosOptions class for configuring the connection to Cosmos:

Name Description
AccountEndpoint URL to the Cosmos Account
AccountKey Key for the Cosmos Account
DatabaseName Name of the Cosmos database (will be provisioned by the library)
DatabaseThroughput Throughput provisioned for the database in Request Units per second
SerializerOptions JsonSerializerOptions used for System.Text.Json.JsonSerializer
Credential TokenCredential for Azure AD authentication. When set, AccountKey is ignored

There are 3 ways to provide the CosmosOptions to the library:

  1. As an argument to the ConfigureCosmos() extension method.

  2. As a Func<IServiceProvider, CosmosOptions> factory method argument on the ConfigureCosmos() extension method.

  3. As an IOptions<CosmosOptions> instance configured using the Options framework and registered in dependency injection.

    This could be done by reading the CosmosOptions from configuration:

    services.Configure<CosmosOptions>(
      Configuration.GetSection(configurationSectionName));
    

    Or by using a factory class implementing the IConfigureOptions<CosmosOptions> interface:

    services.ConfigureOptions<ConfigureCosmosOptions>();
    

    The latter is the recommended approach.

Configure Containers

For each Cosmos resource you want to access using the readers and writers you will need to:

  1. Create a class representing the Cosmos document resource.

    The class should implement the abstract CosmosResource base class, which requires GetDocumentId() and GetPartitionKey() methods to be implemented.

    The class will be serialized using System.Text.Json.JsonSerializer, so JsonPropertyNameAttribute can be used to control property names in the JSON document.

  2. Configure the container used for the Cosmos document resource.

    This is done on the ICosmosBuilder made available using the ConfigureCosmos() extension on IServiceCollection:

    builder.Services.ConfigureCosmos(b => b.AddContainer<MyResource>(containerName));
    
  3. Connect to multiple databases by scoping your container to a new CosmosOptions instance:

    builder.Services.ConfigureCosmos(
        b => b.AddContainer<MyResource>(containerName)
              .ForDatabase(secondDbOptions)
                .AddContainer<MySecondResource>(containerName));
    

    The first call to AddContainer is scoped to the default options. The call to ForDatabase returns a new builder scoped to the provided options.

Initialize Containers

The library supports adding initializers for each container that can create the container and configure it with the correct keys and indexes.

  1. Create an initializer by implementing the ICosmosContainerInitializer interface.

    Usually the implementation will call CreateContainerIfNotExistsAsync() on the provided Database object with the desired ContainerProperties.

  2. Register the initializer on the ICosmosBuilder:

    builder.Services.ConfigureCosmos(b => b.AddContainer<MyInitializer>(containerName));
    
  3. Run the initialization using a hosted service:

    builder.Services.ConfigureCosmos(b => b.UseHostedService());
    

Using the Readers and Writers

Once the setup is in place, the readers and writers are registered with the Microsoft.Extensions.DependencyInjection container and can be obtained via constructor injection.

The bulk reader and writer optimize performance when executing many operations towards Cosmos. They work by creating all the tasks and then using Task.WhenAll() to await them, grouping operations by partition key and sending them in batches of 100.

When not operating with bulks, the normal readers are faster as there is no delay waiting for more work.

Change Feeds

The library supports adding change feed processors for a container.

  1. Create a processor by implementing the IChangeFeedProcessor interface.

  2. Register the change feed processor during initialization:

    builder.Services.ConfigureCosmos(b => b
        .AddContainer<MyInitializer, MyResource>(containerName)
        .WithChangeFeedProcessor<MyChangeFeedProcessor>());
    

    Or using the ICosmosContainerBuilder<T>:

    builder.Services.ConfigureCosmos(b => b
        .AddContainer<MyInitializer>(
          containerName,
          c => c
            .AddResource<MyResource>()
            .WithChangeFeedProcessor<MyChangeFeedProcessor>()));
    

Note: The change feed processor relies on a HostedService, which means this feature is only available in hosted applications.

Delete by Partition Key

The ICosmosWriter<T>.DeletePartitionAsync() method allows you to delete all documents within a partition by partition key. This uses the Cosmos DB delete all items by partition key feature.

Priority Based Execution

The library exposes low priority readers and writers:

Interface Description
ILowPriorityCosmosReader<T> Read Cosmos resources with low priority
ILowPriorityCosmosWriter<T> Write Cosmos resources with low priority
ILowPriorityCosmosBulkReader<T> Bulk read with low priority
ILowPriorityCosmosBulkWriter<T> Bulk write with low priority

The "Priority Based Execution" feature needs to be enabled on the CosmosDB account, either in the Azure Portal under Settings > Features, or via Azure CLI:

az cosmosdb update --resource-group $ResourceGroup --name $AccountName --enable-priority-based-execution true

See Microsoft Learn for more details.

Unit Testing

The reader and writer interfaces can easily be mocked, but in some cases it is useful to have a fake implementation that mimics the behavior of read and write operations. The Atc.Cosmos.Testing namespace provides:

Class Description
FakeCosmosReader<T> Fake ICosmosReader<T> / ICosmosBulkReader<T>
FakeCosmosWriter<T> Fake ICosmosWriter<T> / ICosmosBulkWriter<T>
FakeCosmos<T> Combined fake reader and writer with shared state

Using Atc.Test, a test using the fakes could look like this:

[Theory, AutoNSubstituteData]
public async Task Should_Update_Cosmos_With_NewData(
    [Frozen(Matching.ImplementedInterfaces)]
    FakeCosmos<MyCosmosResource> cosmos,
    MyCosmosService sut,
    MyCosmosResource resource,
    string newData)
{
    cosmos.Documents.Add(resource);

    await sut.UpdateAsync(resource.Id, newData);

    resource
        .Data
        .Should()
        .Be(newData);
}

Sample

See the sample API for an example of how to configure the library with a minimal API, including container initialization, reading, and writing resources.

Requirements

How to contribute

Contribution Guidelines

Coding Guidelines

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 215 8/25/2026
1.1.46 17,483 12/9/2024
1.1.46-preview 152 12/9/2024
1.1.45 10,319 10/21/2024
1.1.45-preview 303 10/21/2024
1.1.44 5,927 9/26/2024
1.1.44-preview 147 9/26/2024
1.1.43 289 9/25/2024
1.1.43-preview 133 9/25/2024
1.1.42 4,028 5/23/2024
1.1.42-preview 143 5/23/2024
1.1.41 4,555 4/25/2024
1.1.41-preview 194 4/25/2024
1.1.40 11,546 9/6/2023
1.1.40-preview 256 9/6/2023
1.0.166 5,538 5/31/2023
1.0.163 380 5/29/2023
1.0.162 1,935 4/26/2023
1.0.160 632 4/20/2023
1.0.158 3,400 2/23/2023
Loading failed