Модели, с которыми я работаю, включают в себя объект ввода, который я хотел бы отобразить, как если бы его дочерний объект был всем объектом.
Вот упрощенная версия проблемы.Мне бы хотелось, чтобы экземпляр OurWrappedSource
отображался непосредственно на OurTarget
.
class OurTarget
{
public Guid Id { get; set; }
public string Notes { get; set; }
public int Quantity { get; set; }
}
class OurSource
{
public Guid Id { get; set; }
public string Notes { get; set; }
public int Quantity { get; set; }
}
class OurWrappedSource
{
public OurSource Source { get; set; }
}
private static void TestUnwrapUsingConfig(MapperConfiguration config)
{
config.AssertConfigurationIsValid();
IMapper mapper = new Mapper(config);
var wrappedSource = new OurWrappedSource
{
Source = new OurSource
{
Id = new Guid("123e4567-e89b-12d3-a456-426655440000"),
Notes = "Why?",
Quantity = 27
}
};
var target = mapper.Map<OurTarget>(wrappedSource);
Assert.Equal(wrappedSource.Source.Id, target.Id);
Assert.Equal(wrappedSource.Source.Notes, target.Notes);
Assert.Equal(wrappedSource.Source.Quantity, target.Quantity);
}
. Следующая конфигурация работает, но громоздка для нескольких членов:
// Works, but isn't *auto* enough
TestUnwrapUsingConfig(new MapperConfiguration(cfg =>
{
cfg.CreateMap<OurWrappedSource, OurTarget>()
.ForMember(src => src.Id, opts => opts.MapFrom(wrappedSource => wrappedSource.Source.Id))
.ForMember(src => src.Notes, opts => opts.MapFrom(wrappedSource => wrappedSource.Source.Notes))
.ForMember(src => src.Quantity, opts => opts.MapFrom(wrappedSource => wrappedSource.Source.Quantity));
}));
Я хотел бы иметь возможность определить два промежуточных отображения и затем составить их:
- Отображение
OurWrappedSource
непосредственно на OurSource
- Отображение
OurSource
непосредственно к OurTarget
- Сопоставить
OurWrappedSource
с OurTarget
, составив отображение 1 с отображением 2
После некоторого удара, у меня есть эта конфигурация:
// Works, but #3 probably isn't ProjectTo-friendly
TestUnwrapUsingConfig(new MapperConfiguration(cfg =>
{
// 1
cfg.CreateMap<OurWrappedSource, OurSource>()
.ConvertUsing(wrappedSource => wrappedSource.Source);
// 2
cfg.CreateMap<OurSource, OurTarget>();
// 3
cfg.CreateMap<OurWrappedSource, OurTarget>()
.ConstructUsing((wrappedSource, ctx) =>
ctx.Mapper.Map<OurTarget>(ctx.Mapper.Map<OurSource>(wrappedSource))
)
.ForAllOtherMembers(opts => opts.Ignore());
}));
Это работает точно так, как указано, но отображение 3 кажется, возможно, немного более явным и / или хитрым, чем следовало бы.Он включает в себя код Func
(а не выражение), что заставляет меня думать, что он, вероятно, не будет хорошо оптимизирован при использовании с ProjectTo()
.Есть ли способ переписать сопоставление 3 для решения этих проблем?