Reputation: 3509
I have a destination class that combines properties from a source class and an inner class of that source class.
class Source {
public int Id {get;set;}
public int UseThisInt {get;set;}
public InnerType Inner {get;set;}
// other properties that the Destination class is not interested in
}
class InnerType {
public int Id {get;set;}
public int Height {get;set;}
// more inner properties
}
my destination class should combine UseThisInt
and all properties of the InnerType
.
class Destination {
public int Id {get;set;}
public int UseThisInt {get;set;}
public int Height {get;set;}
// more inner properties that should map to InnerType
}
Now my AutoMapper configuration looks like this:
CreatMap<Source, Destination>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Inner.Id))
.ForMember(d => d.Height, o => o.MapFrom(s => s.Inner.Height));
AutoMapper will correctly map UseThisInt
between Source
and Destination
, but I would like to be able to let it map all the other properties in Destination like Height
without an explicit ForMember
configuration.
I tried using
Mapper.Initialize(cfg => cfg.CreateMap<Source, Destination>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Inner.Id))
.ForMember(d => d.UseThisInt, o => o.MapFrom(s => s.UseThisInt))
.ForAllOtherMembers(o => o.MapFrom(source=> source.Inner))
);
, but that did not achieve the intended result and left Destination.Height
untouched.
Upvotes: 1
Views: 1227
Reputation: 3441
CreateMap<Source, Destination>()
.AfterMap((src, dest) =>
{
dest.Height = src.Inner.Height;
});
Upvotes: 0
Reputation: 1492
Most examples of AutoMapper demonstrate creating a new Destination object from some source object, but AutoMapper can also be used to update an existing object taking those properties from the source object that are mapped and leaving any remaining properties untouched.
Consequently it is possible to map from the source to the destination in multiple steps.
So if you create a mapping configuration from InnerType
like so:-
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>();
cfg.CreateMap<InnerType, Destination>();
});
Then you can make use of this ability to overlay mappings by mapping into the destination object twice.
var dest = Mapper.Map<Destination>(src);
Mapper.Map(src.Inner, dest);
One downside to this approach is that you need to be mindful of this when using the Mapper to generate a Destination object. However, you have the option of declaring this second mapping step within your AutoMapper configuration as an AfterMap
instruction.
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>()
.AfterMap((src, dest) => Mapper.Map(src.Inner, dest));
cfg.CreateMap<InnerType, Destination>();
});
With this updated configuration you can perform the mapping with a single Map call:-
var dest = Mapper.Map<Destination>(src);
Upvotes: 4