Table of Contents

Mapperly Integration

The MapCrud.Mapperly package provides integration with Riok.Mapperly, a Roslyn source generator that produces high-performance, allocation-free mapping code at compile time.

Prerequisites

Install both packages in your application project:

dotnet add package MapCrud.Mapperly
dotnet add package Riok.Mapperly

Note: MapCrud.Mapperly does not depend on Riok.Mapperly directly — you install Mapperly in your application project for source generation to work.

Setup

Register mappers in DI using AddMapCrudMapperly():

builder.Services.AddMapCrud<AppDbContext>();
builder.Services.AddMapCrudMapperly();  // scans calling assembly for IMapCrudMapper<,> implementations

To scan specific assemblies:

builder.Services.AddMapCrudMapperly(typeof(Program).Assembly, typeof(MyMapper).Assembly);

Writing a Mapper

Create a partial class decorated with [Mapper] that implements IMapCrudMapper<TEntity, TDto>:

using MapCrud.Interfaces;
using Riok.Mapperly.Abstractions;

[Mapper]
public partial class ProductMapper : IMapCrudMapper<Product, ProductDto>
{
    public partial ProductDto Map(Product entity);
    public partial Product Map(ProductDto dto);
    public partial void Map(ProductDto source, Product target);
}

Mapperly generates the implementation at compile time. All three overloads of IMapCrudMapper<,> must be declared as partial methods in the class.

Startup Validation

When AddMapCrudMapperly() is called, MapCrud enables strict mapper validation at startup. If you call MapCrud<T>() with WithRequest<TRequest>() or WithResponse<TResponse>() but no IMapCrudMapper<T, TDto> is registered in DI, MapCrud throws InvalidOperationException immediately at route registration time with a descriptive message:

MapCrud.Mapperly is registered but no IMapCrudMapper<Product, ProductDto> implementation was found.
Create a partial class with [Mapper] attribute implementing IMapCrudMapper<Product, ProductDto>.

This fail-fast behavior prevents silent fallback to ReflectionMapper when Mapperly mode is active.

Example Program.cs

builder.Services.AddMapCrud<AppDbContext>();
builder.Services.AddMapCrudMapperly();

app.MapCrud<Product>("products", o => o
    .WithRequest<CreateProductDto>()
    .WithResponse<ProductDto>());
  • DTO Mapping — ReflectionMapper and the IMapCrudMapper interface