✨ Roslyn source generator for compile-time DTO mapping

AutoMap.Generator
Compile-time object mapping for .NET

Add [Map(typeof(OrderDto))] to your domain class and get a generated ToOrderDto() extension method — zero reflection, AOT-safe, and ready at build time.

$ dotnet add package AutoMap.Generator
your model
using AutoMap;

[Map(typeof(OrderDto))]
public class Order
{
    public int Id { get; set; }
    public string CustomerName { get; set; } = "";
    public decimal Total { get; set; }
}
generated at build time
public static class AutoMapExtensions
{
    public static OrderDto ToOrderDto(this Order source)
        => new()
        {
            Id = source.Id,
            CustomerName = source.CustomerName,
            Total = source.Total,
        };
}

Everything you need

Convention-first mapping with generated extensions, collection helpers, and Roslyn diagnostics.

Zero Reflection

Mapping code is emitted at compile time, not discovered at runtime. Plain generated C# with no reflection or expression compilation.

🧊

AOT-Safe

Works with .NET Native AOT and Blazor WebAssembly. No runtime scanning to break trimming or ahead-of-time compilation.

🧭

Convention-Based

Properties are matched by name automatically, so the common case stays zero-config and easy to read.

🪆

Nested Mapping

When nested source types also have [Map], AutoMap chains the generated calls for you automatically.

📚

Collection Helpers

Generates companion ToXDtos(IEnumerable<X>) helpers so single-object and collection mapping stay consistent.

💡

Roslyn Code Fix

Type mismatch? The IDE lightbulb can add [MapIgnore] for you when a property should be skipped.

Examples

Build-time mapping you can read, debug, and navigate in the IDE.

using AutoMap;

[Map(typeof(OrderDto))]
public class Order
{
    public int Id { get; set; }
    public string CustomerName { get; set; } = "";
    public decimal Total { get; set; }
}

public class OrderDto
{
    public int Id { get; set; }
    public string CustomerName { get; set; } = "";
    public decimal Total { get; set; }
}

// Generated — use it like this:
var dto = order.ToOrderDto();
var dtos = orders.ToOrderDtos(); // collection helper
[Map(typeof(AddressDto))]
public class Address
{
    public string Street { get; set; } = "";
    public string City { get; set; } = "";
}

[Map(typeof(CustomerDto))]
public class Customer
{
    public string Name { get; set; } = "";
    public Address HomeAddress { get; set; } = new();
}

// AutoMap chains them automatically:
var dto = customer.ToCustomerDto();
// dto.HomeAddress is AddressDto — generated null-safe call
[Map(typeof(ProductDto))]
public class Product
{
    public int Id { get; set; }
    public string InternalCode { get; set; } = ""; // rename

    [MapProperty("InternalCode")]   // map to different source property
    public string Sku { get; set; } = "";

    [MapIgnore]                     // skip this property
    public string Secret { get; set; } = "";

    [MapWith("source.Price * 1.2m")] // custom expression
    public decimal PriceWithVat { get; set; }
}
// AutoMap generates a mapper class you can inject:
services.AddSingleton<IAutoMapper<Order, OrderDto>>(
    AutoMapExtensions.OrderToOrderDtoMapper.Instance);

// Inject and use:
public class OrderService(IAutoMapper<Order, OrderDto> mapper)
{
    public OrderDto GetDto(Order order) => mapper.Map(order);
}

Build-time diagnostics

Problems surfaced during compilation — before they become runtime surprises.

Code Severity Description
AM001 ⛔ Error Destination type not found
AM002 ⛔ Error Destination has no settable properties matching source
AM003 ⚠ Warning Property type mismatch — consider [MapWith]
AM004 ⚠ Warning Property skipped due to incompatible type — use [MapIgnore] or add [Map] on source type. IDE lightbulb available.
AM005 ⛔ Error [MapWith] expression cannot be blank
AM006 ⚠ Warning Circular mapping detected

How it compares

Designed for compile-time mapping, runtime simplicity, and AOT-friendly applications.

Feature AutoMap.Generator AutoMapper Mapster
Compile-time generated
Zero reflection
AOT / NativeAOTPartial
IDE navigation to mapping code
Roslyn diagnostics
Runtime config
Projection (IQueryable)

Also by the same author