Skip to content

AutoMapper

Developer UtilitiesUtilitiesC#

What it is

AutoMapper maps between object types by convention, removing hand-written property assignments between entities and DTOs.

Declare mappings in a Profile. Matching property names map automatically; differences are configured explicitly. ProjectTo pushes the mapping into the SQL query.

Installation

dotnet add package AutoMapper

Getting started

The smallest useful thing you can do with it, and what each part means.

Profiles and mapping
public class BookProfile : Profile
{
    public BookProfile()
    {
        CreateMap<Book, BookDto>()
            .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name))
            .ForMember(d => d.Age, o => o.MapFrom(s => DateTime.UtcNow.Year - s.Year));

        CreateMap<CreateBookRequest, Book>()
            .ForMember(d => d.Id, o => o.Ignore());
    }
}

var dto = mapper.Map<BookDto>(book);
Explicit ForMember for anything not name-matched is what keeps the mapping honest. Relying purely on convention is how silently-unmapped properties happen.

Advanced usage

Where the library earns its place over a simpler alternative.

ProjectTo and configuration validation
// Translates the mapping into the SQL SELECT — only the needed
// columns are fetched, and no entities are materialised.
var dtos = await db.Books
    .Where(b => b.Year >= 1990)
    .ProjectTo<BookDto>(mapper.ConfigurationProvider)
    .ToListAsync();

// Fails the build/test if any destination member is unmapped.
[Fact]
public void Mapping_configuration_is_valid() =>
    mapper.ConfigurationProvider.AssertConfigurationIsValid();
AssertConfigurationIsValid in a unit test is essential. Without it, adding a DTO property that AutoMapper cannot resolve silently yields null in production.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Unmapped members were found
That is the validation working. Map the member, or mark it Ignore with a reason.
Missing type map configuration
No CreateMap exists for that pair, or the profile assembly was not registered.

Best practices

  • Always add an AssertConfigurationIsValid test — silent unmapped properties are the main risk.
  • Use ProjectTo for database queries so mapping happens in SQL rather than in memory.
  • Be explicit with ForMember rather than relying on convention for anything non-obvious.
  • Consider hand-written mapping or Mapperly for small projects; explicit code is easier to debug.

Background

Why it exists, and what it was reacting to.

Also by Jimmy Bogard, AutoMapper addressed the tedium of entity-to-DTO mapping. It remains widely used, though opinion has shifted somewhat toward explicit mapping for clarity.