Search code examples
c#automapperdto

C# AutoMapper Custom Resolver based on property names


I'm using AutoMapper (v6.1.1) to map some Entity objects to DTO objects that will be returned by a Web Api REST Web Service in .NET 4.6.2.

Now I manually set my mappings like this:

Mapper.Initialize((config) =>
{
    config.CreateMap<SignBook, sdk.SignBook>()
        .ForMember(dto => dto.DocumentId, conf => conf.MapFrom(obj => obj.Document.Id))
        .ForMember(dto => dto.UserId, conf => conf.MapFrom(obj => obj.User.Id))
        .ForMember(dto => dto.DeviceId, conf => conf.MapFrom(obj => obj.Device.Id))
        .ForMember(dto => dto.SignTypeId, conf => conf.MapFrom(obj => obj.SignType.Id))
        .ForMember(dto => dto.StateId, conf => conf.MapFrom(obj => obj.State.Id))
        .ReverseMap();
});

But, as you can see, all the Properties of DTO object is simply named like the Entity name + "Id" suffix (e.g.: Document.Id in Entity to DocumentId in DTO).

Since I've many Entities to map, I'd like to create a mapping rule for AutoMapper (so create a Custom Resolver) that will do this automatically. Is it possible somehow?

Is there also some best practices when you need to do something like that? So what I want to do is map Entities objects to DTO objects. My Entities are NHibernate objects that has many realtions with each other and also uses Lazy Loading, so I can't push them back directly to Web Api method results to be serialized.


Solution

  • AutoMapper supports Flattening by default. All you need is simple mapping:

    Mapper.Initialize(config =>
    {
        config.CreateMap<SignBook, sdk.SignBook>().ReverseMap();
    });
    

    and starting from AutoMapper 6.1 Unflattening is also supported.


    Flattening:

    var entity = new SignBook { new Document { Id = 42 } };
    var dto = Mapper.Map<sdk.SignBook>(entity);
    

    gives you

    {
      "DocumentId": 42
    }
    

    Unflattening:

    var dto = new sdk.SignBook { DocumentId = 42 };
    var entity = Mapper.Map<SignBook>(dto);
    

    gives

    {
      "Document": {
        "Id": 42
      }
    }