ZeroAlloc.Mapping
1.6.10
dotnet add package ZeroAlloc.Mapping --version 1.6.10
NuGet\Install-Package ZeroAlloc.Mapping -Version 1.6.10
<PackageReference Include="ZeroAlloc.Mapping" Version="1.6.10" />
<PackageVersion Include="ZeroAlloc.Mapping" Version="1.6.10" />
<PackageReference Include="ZeroAlloc.Mapping" />
paket add ZeroAlloc.Mapping --version 1.6.10
#r "nuget: ZeroAlloc.Mapping, 1.6.10"
#:package ZeroAlloc.Mapping@1.6.10
#addin nuget:?package=ZeroAlloc.Mapping&version=1.6.10
#tool nuget:?package=ZeroAlloc.Mapping&version=1.6.10
ZeroAlloc.Mapping
ZeroAlloc.Mapping is a Roslyn source generator that emits strongly-typed Command→Domain→DTO mappers at compile time. No reflection. No expression trees. No runtime configuration. The success path runs with zero allocation beyond the destination instance itself, and the generated code is fully Native AOT compatible.
Install
dotnet add package ZeroAlloc.Mapping
The generator runs automatically as part of dotnet build — there is no DI registration or runtime configuration.
Example
using ZeroAlloc.Mapping;
// 3. Use it
var order = AppMappings.Map(new OrderRequest(42, "rush"));
// 1. Define source and destination
public sealed record OrderRequest(int Id, string Notes);
public sealed record Order(int Id, string Notes);
// 2. Declare the mapper — generator fills in the partial
[Map<OrderRequest, Order>]
public static partial class AppMappings { }
What the generator emits is a null check and a single direct constructor call — no intermediate buffer, no boxing, no closure:
public static Order Map(OrderRequest src)
{
global::System.ArgumentNullException.ThrowIfNull(src);
var __dst = new Order(
Id: src.Id,
Notes: src.Notes
);
return __dst;
}
Performance
ZeroAlloc.Mapping matches Mapperly (the other source-generator mapper) on hot paths and is 1.8–14× faster than AutoMapper on single-object mappings with allocation parity. On the 1000-item collection benchmark AutoMapper is faster but allocates 11% more. Benchmarks below run on .NET 10.0.7, i9-12900HK, BenchmarkDotNet v0.15.8.
| Scenario | ZeroAlloc | Mapperly | AutoMapper | HandWritten |
|---|---|---|---|---|
| FlatIdentity (record copy) | 30.8 ns | 26.3 ns | 76.4 ns | 32.4 ns |
| FlatConversion (string→int) | 185.8 ns | 201.9 ns | 327.2 ns | 167.9 ns |
Flattening (a.b.c → d) |
22.9 ns | 23.0 ns | 70.8 ns | 29.2 ns |
| Polymorphic dispatch | 11.4 ns | 11.0 ns | 48.8 ns | 11.3 ns |
| UpdateInPlace | 6.1 ns | 6.0 ns | 83.9 ns (~14× slower) | 4.7 ns |
| TryMap (Result<T,Error>) | 208.4 ns | 195.4 ns (no native) | — | 222.6 ns |
| Collection (1000 items) | 38.6 µs | 41.1 µs | 30.4 µs | 39.6 µs |
Allocation: identical across mappers except Collection where AutoMapper allocates 11% more (86.5 KB vs 78.2 KB).
See docs/performance.md for the full BenchmarkDotNet output, methodology, and the enforced per-call allocation budgets (CI fails on regression).
Features
[Map<TSrc, TDst>]— direct property/constructor mapping with case-sensitive matching and compile-time diagnostics on mismatch[TryMap<TSrc, TDst>]— fallible mapping returningResult<TDst, MappingError>(integrates with ZeroAlloc.Results smart constructors)[MapProperty]flattening —"Customer.Address.City" → Cityvia dotted paths[BeforeMap]/[AfterMap]hooks — zero overhead when bodies are empty[PolymorphicMap]— type-switch dispatch generated at compile time[ReverseMap]— symmetric Domain↔DTO with a single declaration- Update-in-place — declare
static partial void Map(TSrc src, TDst existingDst)next to[Map<,>]and the generator writes into the existing instance; the whole call allocates nothing, enforced by anAllocationGatetest - Collection overloads —
List<T>,T[],IEnumerable<T>,IReadOnlyList<T>auto-emitted (opt-out via[SkipCollectionOverloads]) [MappingCulture]— culture-awaredecimal.Parse/DateTime.Parseper-mapper- ValueObjects integration — a smart constructor that throws comes back from
TryMapas a failedResultwhoseMappingError.Codeis"mapping.constructor.threw" - Native AOT — no reflection, no
MakeGenericType, no expression compilation; trim/AOT warnings treated as errors in the AOT smoke gate
Documentation
| Page | Description |
|---|---|
| Getting Started | Install + first mapper in five minutes |
| Basic Mapping | Property matching, conversions, customisation |
| Flattening | Dotted source paths via [MapProperty] |
| Collections | Auto-emitted overloads + nested elements |
| Polymorphic | Type-switch dispatch |
| Reverse Mapping | Symmetric Domain↔DTO |
| Update In Place | Allocation-free destination reuse |
| Hooks | [BeforeMap] / [AfterMap] |
| Culture & Strict | [MappingCulture] and strict mode |
| Performance | Benchmarks, allocation budgets, AOT |
| Diagnostics | All ZAMP* diagnostic IDs |
| Testing | How to unit-test generated mappers |
| Advanced | Edge cases, generator internals |
| IQueryable Projection | [Map<,>(Projection = true)] — EF Core expression trees |
| Cycle-Safe Mapping | [Map<,>(CycleSafe = true)] — graphs with back-references |
| Deep Clone | [Map<,>(DeepClone = true)] — whole-graph deep clone |
License
MIT. See LICENSE.
| 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 is compatible. 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
- ZeroAlloc.Results (>= 1.2.4)
-
net8.0
- ZeroAlloc.Results (>= 1.2.4)
-
net9.0
- ZeroAlloc.Results (>= 1.2.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.6.10 | 0 | 10/15/2026 |
| 1.6.9 | 619 | 10/11/2026 |
| 1.6.8 | 1,069 | 9/30/2026 |
| 1.6.7 | 146 | 9/30/2026 |
| 1.6.6 | 531 | 9/28/2026 |
| 1.6.5 | 1,579 | 9/20/2026 |
| 1.6.4 | 117 | 9/20/2026 |
| 1.6.3 | 117 | 9/20/2026 |
| 1.6.2 | 136 | 9/19/2026 |
| 1.6.1 | 1,652 | 8/12/2026 |
| 1.6.0 | 3,366 | 5/24/2026 |
| 1.5.0 | 178 | 5/23/2026 |
| 1.4.1 | 471 | 5/12/2026 |
| 1.4.0 | 358 | 5/10/2026 |
| 1.3.1 | 257 | 5/9/2026 |
| 1.3.0 | 144 | 5/8/2026 |
| 1.2.0 | 140 | 5/8/2026 |
| 1.1.0 | 144 | 5/8/2026 |
| 1.0.0 | 139 | 5/8/2026 |