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,
1public class Entity2{3 public string Name {get;set;}4 public Guid Id {get;set;}5 public string CurrencyCode {get;set;}6 public decimal CurrencyValue {get;set;}7}89public class EntityDto10{11 public string Name {get;set;}12 public Guid Id {get;set;}13 public Currency Currency {get;set;}14}1516public class Currency17{18 public string Code {get;set;}19 public string Value {get;set;}20}
1using AutoMapper;2...34public class SomeService : ISomeService5{6 private IMapper _iMapper;78 public SomeService()9 {10 // One time configuration11 var config = new MapperConfiguration(cfg =>12 {13 cfg.CreateMap<Entity, EntityDto>().ForMember(dto => dto.Currency, map => map.MapFrom(source => new Currency14 {15 Code = source.CurrencyCode,16 Value = source.CurrencyValue.ToString("0.00")17 }));18 });1920 _iMapper = config.CreateMapper();21 }22...23}242526public async Task<DtoClass> GetAsync(Guid id)27{28 Entity entity = await GetEntityByIdAsync(id);2930 // using auto mapper to do the mapping31 var dto = _iMapper.Map<DtoClass>(entity);3233 return dto;34}
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,
1public static class ObjectMapper2{3 private static readonly Lazy<IMapper> Lazy = new Lazy<IMapper>(() =>4 {5 var config = new MapperConfiguration(cfg =>6 {7 // This line ensures that internal properties are also mapped over.8 cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;9 cfg.AddProfile<CustomDtoMapper>();10 });11 var mapper = config.CreateMapper();12 return mapper;13 });1415 public static IMapper Mapper => Lazy.Value;16}
All the mapping configuration goes to,
1public class CustomDtoMapper : Profile2{3 public CustomDtoMapper()4 {5 CreateMap<Entity, EntityDto>().ForMember(dto => dto.Currency, map => map.MapFrom(source => new Currency6 {7 Code = source.CurrencyCode,8 Value = source.CurrencyValue.ToString("0.00")9 }));1011 // All other mappings goes here12 }13}
And use the ObjectMapper where ever you wanted,
1var 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).