AutoMapper is a handy helper library to do mapping between objects. In most scenarios, you might have an Entity Class and you want to map it to some DTO class or vice versa. With minimal configuration, AutoMapper can do this mapping without you creating a method where you map each field one by one.
Suppose I have to map Entity class to EntityDto and they look like,
public class Entity
{
public string Name {get;set;}
public Guid Id {get;set;}
public string CurrencyCode {get;set;}
public decimal CurrencyValue {get;set;}
}
public class EntityDto
{
public string Name {get;set;}
public Guid Id {get;set;}
public Currency Currency {get;set;}
}
public class Currency
{
public string Code {get;set;}
public string Value {get;set;}
}
using AutoMapper;
...
public class SomeService : ISomeService
{
private IMapper _iMapper;
public SomeService()
{
// One time configuration
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Entity, EntityDto>().ForMember(dto => dto.Currency, map => map.MapFrom(source => new Currency
{
Code = source.CurrencyCode,
Value = source.CurrencyValue.ToString("0.00")
}));
});
_iMapper = config.CreateMapper();
}
...
}
public async Task<DtoClass> GetAsync(Guid id)
{
Entity entity = await GetEntityByIdAsync(id);
// using auto mapper to do the mapping
var dto = _iMapper.Map<DtoClass>(entity);
return dto;
}
In the mapping configuration, we didn’t specify anything related Id, Name properties. AutoMapper will map them automatically since the source and destination property name matches for those.
In the above, we defined the mappings in the same class, a better solution would be a common place where we define all the mappings. Let’s do that,
public static class ObjectMapper
{
private static readonly Lazy<IMapper> Lazy = new Lazy<IMapper>(() =>
{
var config = new MapperConfiguration(cfg =>
{
// This line ensures that internal properties are also mapped over.
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
cfg.AddProfile<CustomDtoMapper>();
});
var mapper = config.CreateMapper();
return mapper;
});
public static IMapper Mapper => Lazy.Value;
}
All the mapping configuration goes to,
public class CustomDtoMapper : Profile
{
public CustomDtoMapper()
{
CreateMap<Entity, EntityDto>().ForMember(dto => dto.Currency, map => map.MapFrom(source => new Currency
{
Code = source.CurrencyCode,
Value = source.CurrencyValue.ToString("0.00")
}));
// All other mappings goes here
}
}
And use the ObjectMapper where ever you wanted,
var dto = ObjectMapper.Mapper.Map<DtoClass>(entity);
Read more about the AutoMapper configuration on the official website of AutoMapper.
Additional Resources
Changelog
2020-03-15
- Added common configuration model (ObjectMapper).