Я пытаюсь отобразить следующий сценарий:
// SourceA + SourceB to not derive from a shared base class.
class SourceCollection
{
IList<SourceA> ACollection;
IList<SourceB> BCollection;
// ... other properties ...
}
class DestCollection
{
IList<DestBase> Collection;
// ... other properties ...
}
abstract class DestBase { }
// In their destination form, DestA + DestB share DestBase as a base class.
class DestA : DestBase { }
class DestB : DestBase { }
Когда я сопоставляю SourceCollection> DestCollection, я хочу, чтобы каждая из коллекций была собрана в одну коллекцию. В идеале я хотел бы сделать это без специального распознавателя, поскольку AutoMapper прекрасно понимает, как правильно сопоставить SourceA> DestA и SourceB> DestB. Мне просто нужно понять, что SourceA может отображаться на DestBase как DestA, поскольку DestA происходит от DestBase.
Поскольку нет SourceBase, я не могу просто сопоставить это с DestBase и использовать .Include.
Я предполагаю, что для этого может потребоваться настраиваемый распознаватель, поскольку это две коллекции, объединяющиеся в одну (я бы просто ожидал, что результат будет объединен), но было бы неплохо, если бы он не требовал этого. Или, по крайней мере, я мог бы написать один пользовательский распознаватель, который был бы достаточно универсальным, чтобы его не нужно было менять, если появился SourceC + DestC.
Обновление:
Это ValueResolver, с которым он может быть достигнут, однако он требует учета каждого типа для разрешения вручную:
public class BaseCollectionResolver : ValueResolver< SourceCollection, IList<DestBase> >
{
protected override IList<DestBase> ResolveCore(SourceCollection source)
{
var items = new List<DestBase>();
foreach (var sourceA in source.ACollection)
items.Add( Mapper.Map<SourceA, DestA>(sourceA) );
foreach (var sourceB in source.BCollection)
items.Add( Mapper.Map<SourceB, DestB>(sourceB) );
return items;
}
}
И затем отображается соответственно:
Mapper.CreateMap<SourceCollection, DestCollection>()
.ForMember(dest => dest.Collection, m => m.ResolveUsing<BaseCollectionResolver>());