Author : MD TAREQ HASSAN | Updated : 2020/08/01
What is AutoMapper?
- AutoMapper is an object-to-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type
- See: AutoMapper Usage Guidelines
- Automapper Github repo: https://github.com/AutoMapper/AutoMapper
- Automapper API Doc: https://docs.automapper.org/en/stable/index.html
- How do I test my mappings?
Installation
Install-Package AutoMapper
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Setup
- you only need one MapperConfiguration instance typically per AppDomain and should be instantiated during startup.
- a good way to organize your mapping configurations is with profiles. Create classes that inherit from Profile and put the configuration in the constructor
- if you have only one layer where you need to map between your models, I would recommend not to use AutoMapper Profiles and just go with a simple solution
- profiles allow you to group common configuration and organize mappings by usage. This lets you put mapping configuration closer to where it’s used, instead of a single file of configuration that becomes impossible to edit/maintain
Simple setup
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<FooEntity, FooDto>();
// or
cfg.CreateMap<FooEntity, FooDto>()
.ForMember(dest => dest.FullName, opts => opts.MapFrom(src => $"{src.FirstName} {src.LastName}"));
// ... ... ...
});
var mapper = config.CreateMapper(); // or IMapper mapper = new Mapper(config);
var fooDto = mapper.Map<FooDto>(fooEntity); // type is inferred: var dest = mapper.Map<FooEntity, FooDto>(...)
Simple setup with profile
FooProfile.cs
public class FooProfile : Profile
{
public FooProfile()
{
CreateMap<FooEntity, FooDto>()
.ForMember(dest => dest.FullName, opts => opts.MapFrom(src => $"{src.FirstName} {src.LastName}"));
// ... ... ...
}
}
Using FooProfile
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<FooProfile>();
});
var mapper = config.CreateMapper();
var fooDto = mapper.Map<FooDto>(fooEntity);
AutoMapper in aspnet core with Dependency Injection
- Dependency:
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
AddAutoMapper()
will scan the aspnet core app project (not library project) and add all profiles derived form AutoMapper Profile (you just need to create profiles)- for library project see: https://lostechies.com/jimmybogard/2016/07/20/integrating-automapper-with-asp-net-core-di/
- see: https://stackoverflow.com/questions/40114996/automapper-implementation-in-asp-net-core-mvc
AddAutoMapper()
in Startup.cs
services.AddAutoMapper(typeof(Startup));
// ... ... ...
If models are in different package
services.AddAutoMapper(typeof(a_profile_classe_in_other_assembly).GetTypeInfo().Assembly);
See: https://github.com/AutoMapper/AutoMapper/issues/2300#issuecomment-342157947
Get IMapper by DI
FooService.cs
public class FooService {
private readonly IMapper _mapper;
private readonly IFooRepo _repo;
public UserController(IMapper mapper, IFooRepo repo) {
_mapper = mapper;
_repo = repo;
}
public FooDto GetFoo(long id){
FooEntity fooEntity = _repo.GetFoo(id);
FooDto fooDto = _mapper.Map<FooDto>();
return fooDto
}
// ... ... ...
}
Mappings
Ignore property
// UpdateEmployeeDto => Employee
CreateMap<UpdateEmployeeDto, Employee>().ForMember(dest => dest.Id, opts => opts.Ignore());
Ignore null values
// Just for compying values
CreateMap<Employee, Employee>().ForMember(dest => dest.Id, opts => opts.Ignore())
.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));
See:
- https://stackoverflow.com/questions/43947475/how-to-ignore-null-values-for-all-source-members-during-mapping-in-automapper-6
- To set default value for null: http://docs.automapper.org/en/stable/Null-substitution.html#null-substitution