2010-12-16 4 views
1

の抽象クラスなしのマッピング派生クラスIは、次のシナリオをマップしようとしています:私はSourceCollection> DestCollectionをマップする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 { } 

は、私は、コレクションのそれぞれが単一のコレクションに集めることにしたいです。理想的には、AutoMapperはSourceA> DestAとSourceB> DestB fineのマッピング方法を理解しているので、カスタムリゾルバなしでこれを実行したいと考えています。 DestAがDestBaseから派生しているように、SourceAがDestAとしてDestBaseにマップできることを認識するために必要です。

SourceBaseはありませんので、DestBaseにマップするだけで、.Includeを使用することはできません。

これは、2つのコレクションが1つにマージされているため(カスタム結果のリゾルバを必要とするかもしれないと思いますが)、それを必要としない場合は素晴らしい結果になります。あるいは、少なくとも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; 
    } 
} 

そしてマッパーに追加します。SourceCollectionは現在DestCollectionの罰金にマップする他のプロパティが含まれていますので、そのための

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

おかげで、(私は例ではそれらを左)、ConvertUsingはそれらを防ぐことができますマップされていますか? – Kasaku

+0

@PirateKitten - まったく正直ではありません。とにかく、ITypeConvertersのすべてのマッピングを常に行っているので、私はそれを試したことはありません。試してみて、何が起こるか教えてください:)。 – GenericTypeTea

+0

私はそれが全体のコレクションではなく、そのフィールドのためだけにバリューリゾルバーを必要とすると思います。私はあなたのコードを適応し、私の質問を更新しました。このソリューションは動作しますが、私は既にこのシナリオを処理しているかもしれないAutoMapperの一部があることを願っています:) – Kasaku

関連する問題