I am using AutoMapper 6.2.2, I have two source models that share an Id
property:
using System.Diagnostics;
using AutoMapper;
public class Outer
{
public int Id { get; set; }
public string Foo { get; set; }
public Inner Bar { get; set; }
}
public class Inner
{
public int Id { get; set; }
public string Baz { get; set; }
public string Qux { get; set; }
public string Bof { get; set; }
}
public class FlatDto
{
public int Id { get; set; }
public string Foo { get; set; }
public string Baz { get; set; }
public string Qux { get; set; }
public string Bof { get; set; }
}
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
this.CreateMap<Outer, FlatDto>()
.ForMember(dst => dst.Id, opt => opt.MapFrom(s => s.Id))
.ForMember(dst => dst.Foo, opt => opt.MapFrom(s => s.Foo))
.ForMember(dst => dst.Baz, opt => opt.MapFrom(s => s.Bar.Baz))
.ForMember(dst => dst.Qux, opt => opt.MapFrom(s => s.Bar.Qux))
.ForMember(dst => dst.Bof, opt => opt.MapFrom(s => s.Bar.Bof));
}
}
class Program
{
static void Main(string[] args)
{
Outer model = new Outer
{
Id = 1,
Foo = "FooString",
Bar = new Inner
{
Id = 2,
Baz = "BazString",
Qux = "QuxString",
Bof = "BofString"
}
};
var config = new MapperConfiguration(cfg => cfg.AddProfiles(typeof(Program).Assembly));
config.AssertConfigurationIsValid();
IMapper mapper = new Mapper(config);
FlatDto dto = mapper.Map<Outer, FlatDto>(model);
Trace.Assert(model.Id == dto.Id);
Trace.Assert(model.Foo == dto.Foo);
Trace.Assert(model.Bar.Baz == dto.Baz);
Trace.Assert(model.Bar.Qux == dto.Qux);
Trace.Assert(model.Bar.Bof == dto.Bof);
}
}
I want FlatDto.Id
to come from Outer
and the other parameters all by name. AutoMapper's convention in this case is pretty clear however I cannot modify these properties. It's currently mapped explicitly with ForMember
for every dest property. The solution for a similar question actually is even longer.
Does a more elegant solution exist for this case where both models contain several fields and only one overlaps and requires explicit handling?