Description
Permet le mapping d'un objet de type A vers un objet de type B.
AutoMapper utilise des convention de mapping afin de réduire le paramétrage:
Propriétés de même nom
Flattening
Ignore les références null
Liens
var config = new MapperConfiguration (cfg => {
cfg.CreateMap <Source , Dest >();
cfg.AddProfile <AppProfile >();
cfg.AddProfiles (typeof (ContainerConfig ).Assembly );
});
IMapper mapper = config.CreateMapper ();
IMapper mapper = new Mapper (config);
AProfile.cs
internal sealed class AProfile : Profile
{
public AProfile ()
{
this .CreateAToBMapping ();
this .CreateBToAMapping ();
}
private void CreateAToBMapping ()
{
this .CreateMap <A , B >()
.ForMember (dest => dest .B1 , opt => opt .MapFrom (src => src .A1 ));
}
private void CreateBToAMapping ()
{
this .CreateMap <B , A >()
.ForMember (dest => dest .A1 , opt => opt .MapFrom (src => src .B1 ));
.ForAllOtherMembers (opt => opt .Ignore ());
}
}
Add the nuget package AutoMapper.Extensions.Microsoft.DependencyInjection
Startup.cs
public void ConfigureServices (IServiceCollection services )
{
services.AddAutoMapper (typeof (ProfileTypeFromAssembly1 ), typeof (ProfileTypeFromAssembly2 ));
Exemple
var config = new MapperConfiguration (cfg =>
{
cfg.CreateMap <A , B >()
.ForMember (dst => dst .Q2 , opts => opts .MapFrom (src => src .P2 ));
.ReverseMap ();
});
IMapper mapper = config.CreateMapper ();
C c = new C () { P1 = 3 };
A a = new A () { P1 = 1 , C1 = c };
B b = mapper.Map <B >(a );
class A
{
public int P1 { get ; set ; }
public int P2 { get ; set ; }
public C C1 { get ; set ; }
}
class B
{
public int P1 { get ; set ; }
public int Q2 { get ; set ; }
public int C1P1 { get ; set ; }
}
class C
{
public int P1 { get ; set ; }
}
If the mapping to a destination property has not been configured, you will get an AutoMapper.AutoMapperMappingException
Unflattening
this .CreateMap <UserDto , User >()
.ForPath (dest => dest .Group .Id , opt => opt .MapFrom (src => src .GroupId ));
List and polymorphism
List <B > listB = Mapper.Map <List <A >, List <B >>(listA );
cfg.CreateMap <Parent1 , Parent2 >()
.Include <Child1 , Child2 >();
cfg.CreateMap <Child1 , Child2 >();
var lp1 = new List <Parent1 > { new Parent1 { P1 = 1 }, new Child1 { P1 = 2 , P2 = 22 } };
var lp2 = mapper.Map <List <Parent2 >>(lp1 );
class Parent1
{
public int P1 { get ; set ; }
}
class Child1 : Parent1
{
public int P2 { get ; set ; }
}
class Parent2
{
public int P1 { get ; set ; }
}
class Child2 : Parent2
{
public int P2 { get ; set ; }
}
var config = new MapperConfiguration (cfg =>
{
cfg.CreateMap <A , B >()
.ForMember (dest => dest .P1 ,
opt => opt .MapFrom ((src , dest , destMember , resContext ) => src.P1 + (int )resContext .Items ["+"]));
});
IMapper mapper = config.CreateMapper ();
var a = new A { P1 = 1 };
var b = mapper.Map <B >(a , opt => opt .Items ["+" ] = 9 );
Map 1 object to multiple objects
class Group
{
public int Id { get ; set ; }
public ICollection <int > UserIds { get ; } = new List <int >();
}
class User
{
public int Id { get ; set ; }
public int GroupId { get ; set ; }
}
Flatten to ValueType
afficher var config = new MapperConfiguration (cfg =>
{
cfg.CreateMap <(Group group, int userId), User >()
.IncludeMembers (s => s .group ) // call the mapping Group → User
.ForMember (dest => dest .Id , opt => opt .MapFrom (src => src .userId ));
cfg.CreateMap <Group , User >()
.ForMember (dest => dest .GroupId , opt => opt .MapFrom (src => src .Id ))
.ForMember (dest => dest .Id , opt => opt .Ignore ());
});
IMapper mapper = config.CreateMapper ();
var group = new Group
{
Id = 9 ,
UserIds = {1 , 2 , 3 }
};
IEnumerable <(int groupId, int userId)> groupAndUserList = group .UserIds.Select (x => ValueTuple .Create (group .Id , x ));
var users = mapper.Map <IEnumerable <User >>(groupAndUserList ).ToList ();
Flatten with a ITypeConverter
afficher var config = new MapperConfiguration (cfg =>
{
cfg.CreateMap <int , User >()
.ForMember (dest => dest .Id , opt => opt .MapFrom (src => src ));
cfg.CreateMap <Group , User >()
.ForMember (dest => dest .GroupId , opt => opt .MapFrom (src => src .Id ))
.ForMember (dest => dest .Id , opt => opt .Ignore ());
cfg.CreateMap <Group , IEnumerable <User >>()
.ConvertUsing <GroupToUsersConverter >();
});
IMapper mapper = config.CreateMapper ();
var group = new Group
{
Id = 9 ,
UserIds = { 1 , 2 , 3 }
};
var users = mapper.Map <IEnumerable <User >>(group ).ToList ();
class GroupToUsersConverter : ITypeConverter <Group , IEnumerable <User >>
{
public IEnumerable <User > Convert (
Group source ,
IEnumerable <User > destination ,
ResolutionContext context )
{
foreach (var userId in source.UserIds)
{
var user = context.Mapper.Map <User >(userId );
context.Mapper.Map (source , user );
yield return user;
}
}
}
Errors
this .CreateMap <Class1 , Class2 >()
.ForMember (dest => dest .Prop1 , opt => opt .MapFrom (src =>
{
// ...
}));
this .CreateMap <Class1 , Class2 >()
.ForMember (dest => dest .Prop1 , opt => opt .MapFrom ((src , dest ) =>
{
// ...
}));
var mapperMock = new Mock <IMapper >();
mapperMock.Setup (x => x .Map <ItemDto >(It .IsAny <Item >()))
.Returns (new ItemDto ());
var configuration = new MapperConfiguration (cfg => cfg.AddProfile <ItemProfile >());
configuration.AssertConfigurationIsValid ();
var mapper = configuration.CreateMapper ();
var item = new Item { };
var itemDto = mapper.Map <ItemDto >(item );
var mappedItem = mapper.Map <Item >(itemDto );
Assert.Equal (item .Property1 , mappedItem .Property1 );
Installation
NuGet → AutoMapper
ASP.NET Core
NuGet → AutoMapper.Extensions.Microsoft.DependencyInjection
Startup.cs
public void ConfigureServices (IServiceCollection services )
{
services.AddAutoMapper ();
MyController.cs
private readonly IMapper _mapper ;
public MyController (IMapper mapper )
{
_ mapper = mapper;
B b = _ mapper.Map <A , B >(a );
Configuration dans Profile