簡體   English   中英

AutoMapper-在源端映射沒有抽象類的派生類

[英]AutoMapper - Mapping derived classes without abstract class on source side

我正在嘗試映射以下情況:

// 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可以作為DestA映射到DestBase,因為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>());

我想不出一個不使用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;
    }
}

並將其添加到映射器:

Mapper.CreateMap<SourceCollection, DestCollection>()
    .ConvertUsing<SourceCollectionToDestCollection>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM