AOTMapper is a high-performance, compile-time object mapping library that eliminates runtime reflection overhead by generating mapping code at build time using Roslyn source generators.
- Zero Runtime Reflection: All mapping code is generated at compile-time
- High Performance: Benchmark results show comparable performance with manual mapping
- Compile-Time Safety: Type mismatches and missing properties are caught at build time
- Multiple Mapping Patterns: Support for classic, instance extension, and multi-parameter patterns
- IDE Integration: Full IntelliSense support and code analysis
- Missing Property Detection: Automatic warnings for unmapped properties with code fixes
Install the AOTMapper NuGet package to your project:
dotnet add package AOTMapperpublic class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
public class UserDto
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}AOTMapper supports three different mapping patterns:
public static class UserMappers
{
[AOTMapperMethod]
public static UserDto MapToDto(this IAOTMapper mapper, User input)
{
var output = new UserDto();
output.Name = input.Name;
output.Age = input.Age;
output.Email = input.Email;
return output;
}
}public static class UserMappers
{
[AOTMapperMethod]
public static UserDto MapToDto(this User input)
{
var output = new UserDto();
output.Name = input.Name;
output.Age = input.Age;
output.Email = input.Email;
return output;
}
}For scenarios requiring additional parameters (these are not registered with the mapper but work as direct extension methods):
public static class UserMappers
{
[AOTMapperMethod]
public static UserDto MapToDto(this User input, string defaultEmail)
{
var output = new UserDto();
output.Name = input.Name;
output.Age = input.Age;
output.Email = input.Email ?? defaultEmail;
return output;
}
}// Build the mapper (the extension method is auto-generated)
var mapper = new AOTMapperBuilder()
.AddYourProjectName() // Auto-generated based on your assembly name
.Build();
// Use the mapper
var user = new User { Name = "John", Age = 30, Email = "[email protected]" };
// Classic and single-parameter patterns work through the mapper
var dto = mapper.Map<UserDto>(user);
// Multi-parameter extensions work as direct extension methods
var dtoWithDefault = user.MapToDto("[email protected]");
Console.WriteLine(dto.Name); // JohnAOTMapper automatically detects unmapped properties and provides warnings:
[AOTMapperMethod]
public static UserDto MapToDto(this User input)
{
var output = new UserDto();
output.Name = input.Name;
// Warning: Property 'Age' is not mapped
// Warning: Property 'Email' is not mapped
return output;
}[AOTMapperMethod(disableMissingPropertiesDetection: true)]
public static UserDto MapToDto(this User input)
{
var output = new UserDto();
output.Name = input.Name;
// No warnings will be generated
return output;
}AOTMapper provides automatic code fixes for missing properties. When the analyzer detects unmapped properties, you can use the Quick Fix feature in your IDE to automatically add the missing property assignments.
When you build your project, AOTMapper's source generator:
- Scans for methods marked with
[AOTMapperMethod] - Validates method signatures and property mappings
- Generates registration extension methods like
AddYourAssemblyName() - Creates optimized mapping code with zero runtime reflection
For a method like:
[AOTMapperMethod]
public static UserDto MapToDto(this User input) { /* ... */ }AOTMapper generates:
public static AOTMapperBuilder AddYourProject(this AOTMapperBuilder builder)
{
builder.AddMapper<User, UserDto>((mapper, input) => UserMappers.MapToDto(input));
return builder;
}| Pattern | Registration | Usage | Best For |
|---|---|---|---|
| Classic | ✅ Auto-registered | mapper.Map<T>(input) |
Standard scenarios |
| Instance Extension | ✅ Auto-registered | mapper.Map<T>(input) or input.MapToDto() |
Fluent syntax preference |
| Multi-Parameter | ❌ Not registered | input.MapToDto(param1, param2) |
Complex scenarios with context |
AOTMapper is designed for maximum performance:
- Zero Reflection: All mapping logic is generated at compile-time
- Direct Method Calls: Generated code uses direct method invocations
- Minimal Overhead: Registration and lookup optimized for speed
- Memory Efficient: No runtime code generation or dynamic assemblies
AOTMapper provides rich IDE support:
- IntelliSense: Full autocomplete for generated extension methods
- Error Squiggles: Real-time validation of mapping methods
- Quick Fixes: Automatic generation of missing property assignments
- Go to Definition: Navigate from usage to mapper method definitions