ElBruno.AotMapper.EntityFramework
0.6.0
dotnet add package ElBruno.AotMapper.EntityFramework --version 0.6.0
NuGet\Install-Package ElBruno.AotMapper.EntityFramework -Version 0.6.0
<PackageReference Include="ElBruno.AotMapper.EntityFramework" Version="0.6.0" />
<PackageVersion Include="ElBruno.AotMapper.EntityFramework" Version="0.6.0" />
<PackageReference Include="ElBruno.AotMapper.EntityFramework" />
paket add ElBruno.AotMapper.EntityFramework --version 0.6.0
#r "nuget: ElBruno.AotMapper.EntityFramework, 0.6.0"
#:package ElBruno.AotMapper.EntityFramework@0.6.0
#addin nuget:?package=ElBruno.AotMapper.EntityFramework&version=0.6.0
#tool nuget:?package=ElBruno.AotMapper.EntityFramework&version=0.6.0
ElBruno.AotMapper
AOT-friendly compile-time DTO mapper for .NET πΊοΈ
ElBruno.AotMapper is a Roslyn-based source-generator library that creates compile-time DTO mapping code for .NET. No runtime reflection, no dynamic IL emissionβjust fast, AOT-safe, and predictable generated mappers. Perfect for NativeAOT deployments, trimmed applications, and cloud-native workloads.
Why ElBruno.AotMapper?
- Compile-time generation β All mapping logic is generated during build; zero runtime reflection in the happy path
- AOT & Trimming safe β Works seamlessly with NativeAOT and assembly trimming
- Strong diagnostics β Clear compile-time errors for incomplete or ambiguous mappings
- Performance parity β Generated code stays within 5β15% of hand-written mapping
- EF Core friendly β Optional projection helpers for supported query patterns
- ASP.NET Core ready β Dependency injection helpers for easy service registration
Packages
Why ElBruno.AotMapper vs AutoMapper / Mapperly?
Choosing a mapper depends on your scenario. Here's how we compare:
| Feature | ElBruno.AotMapper | AutoMapper | Mapperly |
|---|---|---|---|
| NativeAOT Safe | β Full | β οΈ Limited | β Full |
| Compile-time Errors | β Yes | β Runtime | β Yes |
| Zero Reflection | β Yes | β Heavy | β Yes |
| EF Core Projections | β Yes (v0.6+) | β οΈ QueryableExtensions | β Yes |
| Custom Converters | β
[MapConverter] |
β ValueResolver | β Custom maps |
| Learning Curve | π’ Minimal | π Moderate | π’ Minimal |
| Runtime Cost | π’ ~5% of hand-coded | π‘ ~30-50% | π’ ~5-10% |
| Feature Richness | π‘ Core scenarios | π’ Extensive | π’ Extensive |
Choose ElBruno.AotMapper if:
- You need NativeAOT deployment or strict trimming
- You want compile-time safety with strong diagnostics
- You're building cloud-native or serverless workloads (less startup time, smaller memory footprint)
- You appreciate minimal dependencies for simple scenarios
Choose AutoMapper if:
- You need maximum configurability (convention-based mapping, conditional mapping, etc.)
- Your codebase is not targeting NativeAOT
- You want battle-tested maturity and extensive plugin ecosystem
Choose Mapperly if:
- You want compile-time generation like ElBruno.AotMapper but don't need EF projection helpers
- You prefer attribute-free or profile-based mapping rules
Quick Start
Installation
Install the core package and the generator (as a dev dependency):
dotnet add package ElBruno.AotMapper
dotnet add package ElBruno.AotMapper.Generator
Define a Mapping
Annotate your destination DTO class with [MapFrom]:
using ElBruno.AotMapper;
// Source entity
public class Customer
{
public string Id { get; set; }
public string Name { get; set; }
public string Tier { get; set; }
}
// Destination DTO with mapping attribute
[MapFrom(typeof(Customer))]
public sealed partial record CustomerDto(string Id, string Name, string Tier);
Build & Use
Just build your projectβthe generator creates extension methods automatically:
var customer = new Customer { Id = "123", Name = "Alice", Tier = "Gold" };
// Generated extension method
CustomerDto dto = customer.ToCustomerDto();
// Also works with LINQ queries (when using ElBruno.AotMapper.EntityFramework)
IQueryable<CustomerDto> dtos = context.Customers.ProjectToCustomerDto();
For more details, see Getting Started Guide.
Supported Mappings
ElBruno.AotMapper supports:
- Classes, records, and structs β All reference and value types
- Nested objects β Recursive mapping of complex object graphs
- Collections β Arrays,
List<T>,IEnumerable<T>, and other collection types - Enums β Enum-to-string and string-to-enum conversion helpers
- Nullable reference types β Full nullability awareness and validation
- Custom property rules β Remap properties, set defaults, and ignore fields
- Partial method hooks β Optional pre/post-mapping customization
- EF Core projections β Safe query translation for supported patterns
See Supported Mappings for complete details and examples.
Core Package: ElBruno.AotMapper
The core package provides the mapping attributes and lightweight abstractions.
dotnet add package ElBruno.AotMapper
Key attributes:
[MapFrom(Type)]β Mark destination type as mappable from a source type[MapProperty(sourceProperty, destinationProperty)]β Remap a property[MapIgnore]β Skip a property in the mapping[MapConverter]β Specify a custom type converter
No runtime dependencies; works standalone in any .NET project.
Generator Package: ElBruno.AotMapper.Generator
The Roslyn incremental source generator that creates mapping code at compile time. Install as a dev dependency:
dotnet add package ElBruno.AotMapper.Generator --prerelease
The generator:
- Scans for
[MapFrom]attributes during build - Generates strongly-typed extension methods (e.g.,
ToCustomerDto()) - Emits compile-time diagnostics for incomplete or invalid mappings
- Works with incremental builds for fast iteration
ASP.NET Core Package: ElBruno.AotMapper.AspNetCore
Streamline dependency injection and ASP.NET Core integration:
dotnet add package ElBruno.AotMapper.AspNetCore
Usage:
Register mappers in your service collection:
var builder = WebApplication.CreateBuilder(args);
// Add AOT mapper services
builder.Services.AddAotMapper();
var app = builder.Build();
// ... your endpoints
Generated mappers are then available as extension methods or injected services.
Entity Framework Core Package: ElBruno.AotMapper.EntityFramework
Simplify EF Core query projections with AOT-safe mappers:
dotnet add package ElBruno.AotMapper.EntityFramework
Usage:
Use generated extension methods for in-memory mapping, or manual Select for projections:
[MapFrom(typeof(Customer))]
public sealed partial record CustomerDto(string Id, string Name, string Tier);
// In-memory mapping (generated extension method)
var dtos = customers.Select(c => c.ToCustomerDto()).ToList();
// EF Core projection (manual Select for SQL translation)
var projected = context.Customers
.Select(c => new CustomerDto(c.Id, c.Name, c.Tier.ToString()))
.ToListAsync();
Important: EF projection support is limited to patterns that translate safely to SQL. See EF Integration Guide for supported and unsupported scenarios.
Building from Source
Clone the repository and build with .NET 8 SDK or later:
git clone https://github.com/elbruno/ElBruno.AotMapper.git
cd ElBruno.AotMapper
# Restore dependencies
dotnet restore ElBruno.AotMapper.slnx
# Build
dotnet build ElBruno.AotMapper.slnx
# Run tests
dotnet test ElBruno.AotMapper.slnx
The solution file (ElBruno.AotMapper.slnx) includes all library, test, and sample projects.
Documentation
- Quick Start Guide β Installation, basic usage, first mapping
- Supported Mappings β Complete feature matrix and examples
- Known Limitations β Current constraints and workarounds
- Diagnostics Reference β All diagnostic IDs and remediation steps
- EF Core Integration β Projection helpers and query translation
- Migration Guide β Migrating from AutoMapper or manual mapping
License
This project is licensed under the MIT License. See LICENSE for details.
π About the Author
Made with β€οΈ by Bruno Capuano (ElBruno)
- π Blog: elbruno.com
- πΊ YouTube: youtube.com/elbruno
- π LinkedIn: linkedin.com/in/elbruno
- π Twitter: twitter.com/elbruno
- ποΈ Podcast: notienenombre.com
Acknowledgments
This library is built on Roslyn and inspired by the .NET ecosystem's move toward compile-time solutions for NativeAOT and trimmed applications. Special thanks to the .NET community for feedback and contributions.
| 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 was computed. 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
- ElBruno.AotMapper (>= 0.6.0)
- Microsoft.EntityFrameworkCore (>= 8.0.0)
-
net8.0
- ElBruno.AotMapper (>= 0.6.0)
- Microsoft.EntityFrameworkCore (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.