Skip to main content

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