[英]AutoMapper - Mapping derived classes without abstract class on source side
I am trying to map the following scenario: 我正在尝试映射以下情况:
// 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 { }
When I map SourceCollection > DestCollection I want each of the collections to be gathered into a single collection. 当我映射SourceCollection> DestCollection时,我希望将每个集合都收集到一个集合中。 Ideally I would like to do this without a custom resolver, since AutoMapper understands how to map SourceA > DestA and SourceB > DestB fine.
理想情况下,我想在没有自定义解析器的情况下执行此操作,因为AutoMapper可以很好地映射SourceA> DestA和SourceB> DestB。 I just need it to realise that SourceA can map to DestBase as DestA, as DestA derives from DestBase.
我只需要认识到SourceA可以作为DestA映射到DestBase,因为DestA是从DestBase派生的。
As there is no SourceBase I can't just map that to DestBase and use .Include. 由于没有SourceBase,因此我不能仅将其映射到DestBase并使用.Include。
I'm guessing this might require a custom resolver since it is two collections merging into one (I would just expect the result to be concatonated), but it would be nice if it didn't require it. 我猜想这可能需要一个自定义解析器,因为它将两个集合合并为一个(我只是希望结果被合并),但是如果不需要它会很好。 Or at least I could write a single custom resolver that was generic enough to not require to be changed if SourceC + DestC came along.
或者至少我可以编写一个通用的自定义解析器,如果出现SourceC + DestC,则不需要更改它。
Update: 更新:
This is a ValueResolver it can be achieved with, however it does require accounting for each type to resolve manually: 这是一个可以实现的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;
}
}
And then mapped accordingly: 然后相应地映射:
Mapper.CreateMap<SourceCollection, DestCollection>()
.ForMember(dest => dest.Collection, m => m.ResolveUsing<BaseCollectionResolver>());
I can't think of a nice way to do it without using an ITypeConverter
: 我想不出一个不使用
ITypeConverter
的好方法:
public class SourceCollectionToDestCollection
: ITypeConverter<SourceCollection, DestCollection>
{
public DestCollection Convert(ResolutionContext context)
{
SourceCollection source = context.SourceValue as SourceCollection;
DestCollection destination = context.DestinationValue as DestCollection
?? new DestCollection();
foreach (var sourceA in source.ACollection)
{
DestA dest = Mapper.Map<SourceA, DestA>(sourceA);
destination.Collection.Add(dest);
}
foreach (var sourceB in source.BCollection)
{
DestB dest = Mapper.Map<SourceB, DestB>(sourceB);
destination.Collection.Add(dest);
}
return destination;
}
}
And add it to the mapper: 并将其添加到映射器:
Mapper.CreateMap<SourceCollection, DestCollection>()
.ConvertUsing<SourceCollectionToDestCollection>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.