Reputation: 1932
I have one source class:
class Source {
public string Name;
public string Field1;
public string Field2;
}
and two destination classes:
class Destination {
public string Name;
public FieldsDto Fields;
}
class FieldsDto {
public string Field1;
public string FieldTwo;
}
How can I map Source.Field1
to Destination.Fields.Field1
and Source.Field2
to Destination.Fields.FieldTwo
?
This code does not work; it would throw an error saying that Custom configuration for members is only supported for top-level individ
ual members on a type1
:
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>()
.ForMember(dest => dest.Fields.Field1, opt => opt.Mapfrom(src => src.Field1)
.ForMember(dest => dest.Fields.FieldTwo, opt => opt.Mapfrom(src => src.Field2);
});
Upvotes: 3
Views: 3503
Reputation: 387557
As mentioned in the comments, in order to map nested properties, you will need to use ForPath
instead of ForMember
. So a full configuration may look like this:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Source, Destination>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(s => s.Name))
.ForPath(dest => dest.Fields.Field1, opt => opt.MapFrom(src => src.Field1))
.ForPath(dest => dest.Fields.FieldTwo, opt => opt.MapFrom(src => src.Field2));
});
If you want to do this dynamically, using member names as string (which appears like something you want to do, as I learned in chat), then you will not be able to use ForPath
easily since that absolutely requires a lambda expression that contains only a member expression.
What you could do is create a lambda expression dynamically for the nested member access. I’m sure you will find enough examples on how to create such lambda expressions on here if you search for it.
The alternative would be to split up the mapping into the separate types. So instead of mapping directly to nested properties of the Destination
, you are mapping the nested object separately. Like this:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Source, FieldsDto>()
.ForMember("Field1", opt => opt.MapFrom("Field1"))
.ForMember("FieldTwo", opt => opt.MapFrom("Field2"));
cfg.CreateMap<Source, Destination>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(s => s.Name))
.ForMember(dest => dest.Fields, opt => opt.MapFrom(s => Mapper.Map<FieldsDto>(s)));
});
Upvotes: 4