Excalibur.Data.DynamoDb
3.0.0-alpha.19
dotnet add package Excalibur.Data.DynamoDb --version 3.0.0-alpha.19
NuGet\Install-Package Excalibur.Data.DynamoDb -Version 3.0.0-alpha.19
<PackageReference Include="Excalibur.Data.DynamoDb" Version="3.0.0-alpha.19" />
<PackageVersion Include="Excalibur.Data.DynamoDb" Version="3.0.0-alpha.19" />
<PackageReference Include="Excalibur.Data.DynamoDb" />
paket add Excalibur.Data.DynamoDb --version 3.0.0-alpha.19
#r "nuget: Excalibur.Data.DynamoDb, 3.0.0-alpha.19"
#:package Excalibur.Data.DynamoDb@3.0.0-alpha.19
#addin nuget:?package=Excalibur.Data.DynamoDb&version=3.0.0-alpha.19&prerelease
#tool nuget:?package=Excalibur.Data.DynamoDb&version=3.0.0-alpha.19&prerelease
Excalibur.Data.DynamoDb
AWS DynamoDB data provider implementation for Excalibur cloud-native data access.
Overview
This package provides a cloud-native data access implementation for AWS DynamoDB, implementing ICloudNativePersistenceProvider from Excalibur.Data.Abstractions.
Features
- Document Operations: Full CRUD support for DynamoDB documents
- Batch Operations: Efficient transactional batch creates and replaces using
TransactWriteItems - Query Support: Partition key and sort key queries with pagination
- Change Feed: DynamoDB Streams integration for real-time change data capture
- Health Checks: Built-in health check for monitoring connectivity
- Resilience: Configurable retry policies for transient failures
Installation
dotnet add package Excalibur.Data.DynamoDb
Configuration
Using Options Action
services.AddDynamoDb(options =>
{
options.Region = "us-east-1";
options.DefaultTableName = "MyTable";
options.DefaultPartitionKeyAttribute = "pk";
options.DefaultSortKeyAttribute = "sk";
});
Using Configuration Section
services.AddDynamoDb(Configuration.GetSection("DynamoDb"));
appsettings.json
{
"DynamoDb": {
"Region": "us-east-1",
"DefaultTableName": "MyTable",
"DefaultPartitionKeyAttribute": "pk",
"DefaultSortKeyAttribute": "sk",
"UseConsistentReads": false,
"TimeoutInSeconds": 30,
"MaxRetryAttempts": 3
}
}
Using Existing Client
If you already have an IAmazonDynamoDB client configured:
services.AddSingleton<IAmazonDynamoDB>(sp => new AmazonDynamoDBClient());
services.AddDynamoDbWithClient(options =>
{
options.DefaultTableName = "MyTable";
});
Configuration Options
Connection Settings
| Option | Default | Description |
|---|---|---|
Name |
DynamoDb |
Provider instance name for identification |
Region |
null | AWS region (e.g., "us-east-1") |
ServiceUrl |
null | Custom service URL (for local development) |
AccessKey |
null | AWS access key (optional, uses default credentials if not set) |
SecretKey |
null | AWS secret key (optional, uses default credentials if not set) |
DefaultTableName |
Required | Default table for operations |
Table Key Settings
| Option | Default | Description |
|---|---|---|
DefaultPartitionKeyAttribute |
pk |
Partition key attribute name |
DefaultSortKeyAttribute |
sk |
Sort key attribute name |
Performance Settings
| Option | Default | Description |
|---|---|---|
UseConsistentReads |
false |
Enable strongly consistent reads by default |
TimeoutInSeconds |
30 |
Request timeout |
MaxRetryAttempts |
3 |
Maximum retry attempts for transient failures |
ReadCapacityUnits |
null | On-demand scaling hint for reads |
WriteCapacityUnits |
null | On-demand scaling hint for writes |
DynamoDB Streams Settings
| Option | Default | Description |
|---|---|---|
EnableStreams |
false |
Enable DynamoDB Streams for change data capture |
StreamViewType |
NEW_AND_OLD_IMAGES |
What data to include in stream records |
Stream View Types:
KEYS_ONLY- Only the key attributesNEW_IMAGE- The entire item after modificationOLD_IMAGE- The entire item before modificationNEW_AND_OLD_IMAGES- Both the new and old item images
Usage
Basic Operations
public class MyService
{
private readonly ICloudNativePersistenceProvider _provider;
public MyService(ICloudNativePersistenceProvider provider)
{
_provider = provider;
}
public async Task<Order?> GetOrderAsync(string customerId, string orderId)
{
return await _provider.GetByIdAsync<Order>(
orderId,
new PartitionKey(customerId));
}
public async Task CreateOrderAsync(Order order)
{
await _provider.CreateAsync(
order,
new PartitionKey(order.CustomerId));
}
public async Task<IReadOnlyList<Order>> GetCustomerOrdersAsync(string customerId)
{
return await _provider.QueryAsync<Order>(new PartitionKey(customerId));
}
}
Batch Operations
// Batch create
var items = new[] { order1, order2, order3 };
await _provider.BatchCreateAsync(
items,
item => new PartitionKey(item.CustomerId));
// Batch replace with optimistic concurrency
await _provider.BatchReplaceAsync(
items,
item => new PartitionKey(item.CustomerId),
item => item.ETag);
Change Feed (DynamoDB Streams)
var subscription = await _provider.CreateChangeFeedSubscriptionAsync<Order>(
"Orders",
new ChangeFeedOptions
{
StartPosition = ChangeFeedStartPosition.Beginning,
MaxBatchSize = 100
});
await foreach (var change in subscription.ReadChangesAsync(cancellationToken))
{
Console.WriteLine($"{change.EventType}: {change.DocumentId}");
if (change.Document != null)
{
// Process the changed document
}
}
Note: DynamoDB Streams must be enabled on the table for change feed to work.
Health Check
services.AddHealthChecks()
.AddCheck<DynamoDbHealthCheck>("dynamodb");
Local Development
For local development with DynamoDB Local:
services.AddDynamoDb(options =>
{
options.ServiceUrl = "http://localhost:8000";
options.DefaultTableName = "LocalTable";
});
Key Patterns
This provider follows the single-table design pattern commonly used with DynamoDB:
- Partition Key (pk): Groups related items together for efficient access
- Sort Key (sk): Provides ordering within a partition and enables range queries
Documents are serialized to/from DynamoDB using JSON, with partition and sort keys automatically managed.
Transactional Support
Batch operations use DynamoDB's TransactWriteItems for atomic, all-or-nothing operations:
// All items are created atomically
await _provider.BatchCreateAsync(items, item => new PartitionKey(item.Id));
Error Handling
The provider maps DynamoDB exceptions to CloudOperationResult<T>:
var result = await _provider.UpdateAsync(order, partitionKey, etag);
if (!result.Success)
{
switch (result.StatusCode)
{
case 400:
Console.WriteLine("Validation error or bad request");
break;
case 404:
Console.WriteLine("Item not found");
break;
case 409:
Console.WriteLine("Conditional check failed (item already exists)");
break;
case 412:
Console.WriteLine("Precondition failed (ETag/version mismatch)");
break;
case 429:
Console.WriteLine("Provisioned throughput exceeded - retry with backoff");
break;
}
}
DynamoDB-Specific Exceptions
| Exception | HTTP Status | Description |
|---|---|---|
ConditionalCheckFailedException |
409/412 | Condition expression evaluated to false |
ProvisionedThroughputExceededException |
429 | Exceeded provisioned capacity |
ResourceNotFoundException |
404 | Table or item not found |
TransactionCanceledException |
409 | Transaction failed (conflicts) |
ItemCollectionSizeLimitExceededException |
400 | Item collection too large (10GB limit) |
Authentication
DynamoDB supports multiple authentication methods:
IAM Role (Recommended for AWS)
// Uses default credentials chain (EC2 instance profile, ECS task role, etc.)
services.AddDynamoDb(options =>
{
options.Region = "us-east-1";
options.DefaultTableName = "MyTable";
});
Explicit Credentials
services.AddDynamoDb(options =>
{
options.Region = "us-east-1";
options.AccessKey = "YOUR_ACCESS_KEY";
options.SecretKey = "YOUR_SECRET_KEY";
options.DefaultTableName = "MyTable";
});
Environment Variables
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_REGION="us-east-1"
Best Practices
- Use Single-Table Design - Store related entities in one table using partition/sort key patterns
- Design for Access Patterns - Model your data based on query requirements, not relational concepts
- Enable Consistent Reads Only When Needed - Eventually consistent reads use half the RCUs
- Use Transactional Batches for atomic operations across items
- Monitor Consumed Capacity - Track
ConsumedCapacityin responses - Enable Streams for Event-Driven architectures and change data capture
- Use Exponential Backoff for
ProvisionedThroughputExceededException - Consider On-Demand Mode for unpredictable workloads
License
See LICENSE files in the repository root.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net10.0
- AWSSDK.Core (>= 4.0.3.8)
- AWSSDK.DynamoDBStreams (>= 4.0.4.11)
- AWSSDK.DynamoDBv2 (>= 4.0.10.7)
- AWSSDK.Extensions.NETCore.Setup (>= 4.0.3.19)
- AWSSDK.SecurityToken (>= 4.0.5.6)
- Ben.Demystifier (>= 0.4.1)
- CloudNative.CloudEvents (>= 2.8.0)
- CloudNative.CloudEvents.SystemTextJson (>= 2.8.0)
- Cronos (>= 0.11.1)
- Dapper (>= 2.1.66)
- Excalibur.A3.Abstractions (>= 3.0.0-alpha.19)
- Excalibur.Cdc (>= 3.0.0-alpha.19)
- Excalibur.Data.Abstractions (>= 3.0.0-alpha.19)
- Excalibur.EventSourcing (>= 3.0.0-alpha.19)
- Medo.Uuid7 (>= 1.4.0)
- MemoryPack (>= 1.21.4)
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.AspNetCore.Authorization (>= 9.0.9)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.0)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- MongoDB.Driver (>= 2.25.0)
- NCrontab (>= 3.4.0)
- Npgsql (>= 9.0.4)
- OpenTelemetry (>= 1.13.0)
- OpenTelemetry.Api (>= 1.13.0)
- OpenTelemetry.Extensions.Hosting (>= 1.13.0)
- QuestPDF (>= 2024.12.2)
- Snappier (>= 1.2.0)
- System.Threading.RateLimiting (>= 10.0.0)
-
net8.0
- AWSSDK.Core (>= 4.0.3.8)
- AWSSDK.DynamoDBStreams (>= 4.0.4.11)
- AWSSDK.DynamoDBv2 (>= 4.0.10.7)
- AWSSDK.Extensions.NETCore.Setup (>= 4.0.3.19)
- AWSSDK.SecurityToken (>= 4.0.5.6)
- Ben.Demystifier (>= 0.4.1)
- CloudNative.CloudEvents (>= 2.8.0)
- CloudNative.CloudEvents.SystemTextJson (>= 2.8.0)
- Cronos (>= 0.11.1)
- Dapper (>= 2.1.66)
- Excalibur.A3.Abstractions (>= 3.0.0-alpha.19)
- Excalibur.Cdc (>= 3.0.0-alpha.19)
- Excalibur.Data.Abstractions (>= 3.0.0-alpha.19)
- Excalibur.EventSourcing (>= 3.0.0-alpha.19)
- Medo.Uuid7 (>= 1.4.0)
- MemoryPack (>= 1.21.4)
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.AspNetCore.Authorization (>= 9.0.9)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.0)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- MongoDB.Driver (>= 2.25.0)
- NCrontab (>= 3.4.0)
- Npgsql (>= 9.0.4)
- OpenTelemetry (>= 1.13.0)
- OpenTelemetry.Api (>= 1.13.0)
- OpenTelemetry.Extensions.Hosting (>= 1.13.0)
- QuestPDF (>= 2024.12.2)
- Snappier (>= 1.2.0)
- System.Diagnostics.DiagnosticSource (>= 10.0.0)
- System.IO.Pipelines (>= 10.0.0)
- System.Threading.Channels (>= 10.0.0)
- System.Threading.RateLimiting (>= 10.0.0)
-
net9.0
- AWSSDK.Core (>= 4.0.3.8)
- AWSSDK.DynamoDBStreams (>= 4.0.4.11)
- AWSSDK.DynamoDBv2 (>= 4.0.10.7)
- AWSSDK.Extensions.NETCore.Setup (>= 4.0.3.19)
- AWSSDK.SecurityToken (>= 4.0.5.6)
- Ben.Demystifier (>= 0.4.1)
- CloudNative.CloudEvents (>= 2.8.0)
- CloudNative.CloudEvents.SystemTextJson (>= 2.8.0)
- Cronos (>= 0.11.1)
- Dapper (>= 2.1.66)
- Excalibur.A3.Abstractions (>= 3.0.0-alpha.19)
- Excalibur.Cdc (>= 3.0.0-alpha.19)
- Excalibur.Data.Abstractions (>= 3.0.0-alpha.19)
- Excalibur.EventSourcing (>= 3.0.0-alpha.19)
- Medo.Uuid7 (>= 1.4.0)
- MemoryPack (>= 1.21.4)
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.AspNetCore.Authorization (>= 9.0.9)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.0)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- MongoDB.Driver (>= 2.25.0)
- NCrontab (>= 3.4.0)
- Npgsql (>= 9.0.4)
- OpenTelemetry (>= 1.13.0)
- OpenTelemetry.Api (>= 1.13.0)
- OpenTelemetry.Extensions.Hosting (>= 1.13.0)
- QuestPDF (>= 2024.12.2)
- Snappier (>= 1.2.0)
- System.Diagnostics.DiagnosticSource (>= 10.0.0)
- System.Threading.Channels (>= 10.0.0)
- System.Threading.RateLimiting (>= 10.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Excalibur.Data.DynamoDb:
| Package | Downloads |
|---|---|
|
Excalibur.EventSourcing.DynamoDb
AWS DynamoDB event store implementation for Excalibur event sourcing. |
|
|
Excalibur.Outbox.DynamoDb
AWS DynamoDB implementation of the cloud-native outbox pattern for Excalibur event sourcing. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-alpha.19 | 36 | 2/26/2026 |