Configuration
Configure FluentDynamoDb for your application using FluentDynamoDbOptions.
FluentDynamoDbOptions Overview
FluentDynamoDbOptions is the central configuration object for FluentDynamoDb. It uses an immutable builder pattern where each configuration method returns a new instance with the updated settings.
// Basic usage - no optional features
var client = new AmazonDynamoDBClient();
var table = new UsersTable(client, "users");
// With configuration options
var options = new FluentDynamoDbOptions()
.WithLogger(logger);
var table = new UsersTable(client, "users", options);
Default Options
When you don't need any optional features, create a table without options:
var client = new AmazonDynamoDBClient();
var table = new UsersTable(client, "users");
Or explicitly pass default options:
var options = new FluentDynamoDbOptions();
var table = new UsersTable(client, "users", options);
Logging Configuration
Use WithLogger() to enable logging for DynamoDB operations.
With Microsoft.Extensions.Logging
Install the logging extensions package:
dotnet add package Oproto.FluentDynamoDb.Logging.Extensions
Configure logging using the ToDynamoDbLogger() extension method:
using Oproto.FluentDynamoDb;
using Oproto.FluentDynamoDb.Logging.Extensions;
// From ILogger
var logger = loggerFactory.CreateLogger<UsersTable>();
var options = new FluentDynamoDbOptions()
.WithLogger(logger.ToDynamoDbLogger());
var table = new UsersTable(client, "users", options);
// From ILoggerFactory
var options = new FluentDynamoDbOptions()
.WithLogger(loggerFactory.ToDynamoDbLogger<UsersTable>());
var table = new UsersTable(client, "users", options);
With Custom Logger
Implement IDynamoDbLogger for custom logging:
using Oproto.FluentDynamoDb.Logging;
public class MyCustomLogger : IDynamoDbLogger
{
public bool IsEnabled(LogLevel logLevel) => logLevel >= LogLevel.Information;
public void LogTrace(int eventId, string message, params object[] args) { }
public void LogDebug(int eventId, string message, params object[] args) { }
public void LogInformation(int eventId, string message, params object[] args)
{
Console.WriteLine($"[INFO] [{eventId}] {string.Format(message, args)}");
}
public void LogWarning(int eventId, string message, params object[] args)
{
Console.WriteLine($"[WARN] [{eventId}] {string.Format(message, args)}");
}
public void LogError(int eventId, string message, params object[] args)
{
Console.WriteLine($"[ERROR] [{eventId}] {string.Format(message, args)}");
}
public void LogError(int eventId, Exception exception, string message, params object[] args)
{
Console.WriteLine($"[ERROR] [{eventId}] {string.Format(message, args)}: {exception}");
}
public void LogCritical(int eventId, Exception exception, string message, params object[] args)
{
Console.WriteLine($"[CRITICAL] [{eventId}] {string.Format(message, args)}: {exception}");
}
}
var options = new FluentDynamoDbOptions()
.WithLogger(new MyCustomLogger());
var table = new UsersTable(client, "users", options);
Optional Features
Geospatial Support
Enable geospatial features (GeoHash, S2, H3) with AddGeospatial().
dotnet add package Oproto.FluentDynamoDb.Geospatial
using Oproto.FluentDynamoDb;
var options = new FluentDynamoDbOptions()
.AddGeospatial();
var table = new LocationsTable(client, "locations", options);
Blob Storage
Enable large object storage in S3 with WithBlobStorage().
dotnet add package Oproto.FluentDynamoDb.BlobStorage.S3
using Oproto.FluentDynamoDb.BlobStorage.S3;
var s3Client = new AmazonS3Client();
var blobProvider = new S3BlobProvider(s3Client, "my-bucket");
var options = new FluentDynamoDbOptions()
.WithBlobStorage(blobProvider);
var table = new DocumentsTable(client, "documents", options);
Encryption
Enable field-level encryption with AWS KMS using WithEncryption().
dotnet add package Oproto.FluentDynamoDb.Encryption.Kms
using Oproto.FluentDynamoDb.Encryption.Kms;
var keyResolver = new DefaultKmsKeyResolver("arn:aws:kms:us-east-1:123456789012:key/my-key");
var encryptor = new AwsEncryptionSdkFieldEncryptor(keyResolver);
var options = new FluentDynamoDbOptions()
.WithEncryption(encryptor);
var table = new SecretsTable(client, "secrets", options);
Combining Configuration Options
Chain configuration methods to enable multiple features:
var options = new FluentDynamoDbOptions()
.WithLogger(loggerFactory.ToDynamoDbLogger<MyTable>())
.AddGeospatial()
.WithBlobStorage(blobProvider)
.WithEncryption(encryptor);
var table = new MyTable(client, "my-table", options);
The order of method calls doesn't matter—each method returns a new instance with all previous settings preserved.
Test Isolation
Each table instance has its own configuration, which provides excellent test isolation:
[Fact]
public async Task Test_WithMockLogger()
{
var mockLogger = new MockDynamoDbLogger();
var options = new FluentDynamoDbOptions()
.WithLogger(mockLogger);
var table = new UsersTable(client, "test-users", options);
// Test operations...
Assert.True(mockLogger.LoggedMessages.Any());
}
[Fact]
public async Task Test_WithoutLogging()
{
// No logging configured - uses NoOpLogger by default
var table = new UsersTable(client, "test-users");
// Test operations...
}
Parallel Test Support
Because configuration is instance-based rather than static, tests can run in parallel without interference:
// These tests can run in parallel safely
[Fact]
public async Task Test1()
{
var options = new FluentDynamoDbOptions()
.WithLogger(logger1);
var table = new UsersTable(client, "table1", options);
// ...
}
[Fact]
public async Task Test2()
{
var options = new FluentDynamoDbOptions()
.WithLogger(logger2);
var table = new UsersTable(client, "table2", options);
// ...
}
Next Steps
- Core Concepts - Understand entities, tables, and operations
- Querying - Learn advanced query patterns
- Source Generation - How the source generator works