Skip to main content

AOT Compatibility

FluentDynamoDB is fully compatible with .NET Native AOT compilation.

What is Native AOT?​

Native AOT compiles your application to native code ahead of time, resulting in:

  • Faster startup times
  • Lower memory usage
  • Smaller deployment size
  • No JIT compilation overhead

How FluentDynamoDB Achieves AOT Compatibility​

  • Source generators eliminate runtime reflection
  • No dynamic code generation
  • All types known at compile time
  • Trimming-safe design

Configuration​

Basic AOT Setup​

For AOT compatibility, use source-generated JSON serialization with JsonSerializerContext:

using System.Text.Json.Serialization;
using Oproto.FluentDynamoDb;
using Oproto.FluentDynamoDb.SystemTextJson;

// 1. Define your JSON context with all types that need serialization
[JsonSerializable(typeof(DocumentContent))]
[JsonSerializable(typeof(List<string>))]
[JsonSerializable(typeof(Dictionary<string, object>))]
public partial class AppJsonContext : JsonSerializerContext
{
}

// 2. Configure FluentDynamoDbOptions with the context
var options = new FluentDynamoDbOptions()
.WithSystemTextJson(AppJsonContext.Default);

var table = new DocumentTable(dynamoDbClient, "documents", options);

Entity Definition for AOT​

[DynamoDbTable("documents")]
public partial class Document
{
[PartitionKey]
[DynamoDbAttribute("pk")]
public string Pk { get; set; } = string.Empty;

[SortKey]
[DynamoDbAttribute("sk")]
public string Sk { get; set; } = string.Empty;

[DynamoDbAttribute("title")]
public string Title { get; set; } = string.Empty;

// JSON blob properties require JsonSerializerContext for AOT
[JsonBlob]
[DynamoDbAttribute("content")]
public DocumentContent Content { get; set; } = new();
}

public class DocumentContent
{
public string Body { get; set; } = string.Empty;
public List<string> Tags { get; set; } = new();
}

CRUD Operations​

All standard operations work with AOT compilation:

// Create
var document = new Document
{
Pk = Document.Keys.Pk("doc123"),
Sk = Document.Keys.Sk(),
Title = "My Document",
Content = new DocumentContent
{
Body = "Document body",
Tags = new List<string> { "aot", "example" }
}
};

await table.Documents.PutAsync(document);

// Read
var retrieved = await table.Documents.GetAsync("doc123");

// Query
var results = await table.Documents.Query()
.Where(x => x.Title == "My Document")
.ToListAsync();

// Update
await table.Documents.Update("doc123")
.Set(x => new { Title = "Updated Title" })
.UpdateAsync();

// Delete
await table.Documents.DeleteAsync("doc123");

Publishing for AOT​

dotnet publish -c Release -r linux-x64 -p:PublishAot=true

Project File Configuration​

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<PublishAot>true</PublishAot>
<TrimMode>full</TrimMode>
</PropertyGroup>
</Project>

Benefits for Serverless​

Native AOT is ideal for AWS Lambda and other serverless environments where cold start time matters:

  • Cold start reduction: Up to 80% faster cold starts
  • Memory efficiency: Lower memory footprint
  • Consistent performance: No JIT warmup period

Lambda Example​

public class Function
{
private readonly DocumentTable _table;

public Function()
{
var client = new AmazonDynamoDBClient();
var options = new FluentDynamoDbOptions()
.WithSystemTextJson(AppJsonContext.Default);

_table = new DocumentTable(client, "documents", options);
}

public async Task<Document?> FunctionHandler(string documentId, ILambdaContext context)
{
return await _table.Documents.GetAsync(documentId);
}
}

Troubleshooting​

Missing Types in JsonSerializerContext​

If you see serialization errors at runtime, ensure all types used in [JsonBlob] properties are registered:

// Register all types that appear in JSON blobs
[JsonSerializable(typeof(DocumentContent))]
[JsonSerializable(typeof(UserPreferences))]
[JsonSerializable(typeof(List<string>))]
[JsonSerializable(typeof(Dictionary<string, string>))]
public partial class AppJsonContext : JsonSerializerContext
{
}

Trimming Warnings​

If you see trimming warnings during publish, ensure your entities are partial classes so the source generator can add the necessary code:

// Correct - partial class
[DynamoDbTable("documents")]
public partial class Document { }

// Incorrect - will cause trimming issues
[DynamoDbTable("documents")]
public class Document { }