2010-12-16 32 views
1

我試圖映射以下情形:AutoMapper - 沒有抽象類,測繪類源側

// 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。

我猜這可能需要一個自定義的解析器,因爲它是兩個集合合併成一個(我只希望結果是concaconated),但它會很好,如果它不需要它。或者至少我可以編寫一個自定義解析器,該解析器通用性足以在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>()); 

回答

1

我想不到一個很好的方法來做到這一點,而不使用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>(); 
+0

感謝,由於SourceCollection將包含目前映射到DestCollection精細其他屬性(我離開他們出的例子),將ConvertUsing阻止他們從映射? – Kasaku 2010-12-16 10:52:51

+0

@PirateKitten - 說實話,我不知道。我從來沒有嘗試過,因爲無論如何我總是在ITypeConverters中做所有的映射。試試看,讓我知道會發生什麼:)。 – GenericTypeTea 2010-12-16 10:54:14

+0

我認爲它需要一個價值解析器只爲該領域,而不是一個完整的集合。我修改了你的代碼並更新了我的問題。此解決方案的工作原理,但我會堅持希望有一部分AutoMapper,我錯過了可能已經處理這種情況:) – Kasaku 2010-12-16 11:18:42