2016-05-26 8 views
3

でジャストyestardayを働いていない私は、この投稿:今、私はジミー・ボガード@何をやろうとしているAutomapper - 継承マッパー構築物

Automapper - Inheritance mapper not working with type converter

は、残念ながらまだ成功して、彼の答えで述べています。ベースメンバーはマップされません。

ジミーは言った:

しかし、あなたが最初の 先のオブジェクトを構築するためにConstructUsingを使用することができます。カスタムAfterMapも継承されています。ただ 変換しません。

ここに私の新しいコードがあります。

/* BaseClassConstructor.cs */ 
public class BaseClassConstructor { 
    public static BaseClass Construct(ResolutionContext context) { 
     if (context == null || context.IsSourceValueNull) 
      return null; 

     var src = (SourceClass)context.SourceValue; 

     return new BaseClass() { 
      CommonAttr = src.SourceAttr 
     }; 
    } 
} 

/* AutoMapperConfig.cs */ 
public static class AutoMapperConfig { 

    public static void RegisterMappings() { 
     AutoMapper.Mapper.Initialize(config => { 
     config 
      .CreateMap<SourceClass, BaseClass>() 
      .Include<SourceClass, DerivedClass1>() 
      .Include<SourceClass, DerivedClass2>() 
      .ConstructUsing(s => BaseClassConstructor.Construct(s)); 

     config 
      .CreateMap<SourceClass, DerivedClass1>() 
      .ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2)) 
      .IncludeBase<SourceClass, BaseClass>(); 
     }); 
    } 
} 

私は何かを見逃しましたか? 私は正しい方法でコンストラクションを使用していますか?

ご協力いただければ幸いです。

+0

達成したいことは何ですか? Mapper.Map (ソース)を動作させるには? – Evk

+0

はい! @エヴァーク。すべての基本属性が正しくマップされます。 – arosgab

+0

あなたはタイプコンバータを使用する必要がありますか?あなたの例ではあなたは本当にそれを必要としないからです。 – Evk

答えて

2

あなたはDerived1クラスにソースをマップするときながらConstructUsingにあなたは、BaseClassのインスタンスを作成しますので、それは、動作しませんあなたは今それを行う方法 - あなたはDerived1クラスのインスタンスを必要とし、BaseClassはそれに変換することはできません(ダウンキャスト)。

public class BaseClassConstructor { 
    public static T Construct<T>(ResolutionContext context) where T : BaseClass, new() { 
     if (context == null || context.IsSourceValueNull) 
      return null; 

     var src = (SourceClass) context.SourceValue; 

     return new T() { 
      CommonAttr = src.SourceAttr 
     }; 
    } 
} 

/* AutoMapperConfig.cs */ 
public static class AutoMapperConfig 
{ 

    public static void RegisterMappings() 
    { 
     AutoMapper.Mapper.Initialize(config => { 
      config 
       .CreateMap<SourceClass, BaseClass>(); 

      config 
       .CreateMap<SourceClass, DerivedClass1>() 
       .ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2)) 
       .IncludeBase<SourceClass, BaseClass>() 
       .ConstructUsing((s, ctx) => BaseClassConstructor.Construct<DerivedClass1>(ctx)); 

      config 
       .CreateMap<SourceClass, DerivedClass2>() 
       .ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2)) 
       .IncludeBase<SourceClass, BaseClass>() 
       .ConstructUsing((s, ctx) => BaseClassConstructor.Construct<DerivedClass2>(ctx)); 
     }); 
    } 
} 

基本的に私はあまりにも派生クラスのインスタンスを返し、その後、ConstructUsingを使用するようにConstruct方法に変更はなく、基底クラスマッピングのが、Derivedクラスのマッピングについて:しかし、あなたはこのようにそれを行うことができます。

+0

ありがとう!あなたは私をたくさん助けてくれました。しかし、私は継承マッピングの必要性を見ません。私は基本マッピングを削除し、IncludeBaseコールを使わずに派生クラスを残しました。基本マッピングは実際に派生マッピングで行われるため、すべて正常に動作します。 – arosgab

+0

はい、実際の状況では、ForMemberを使用して基本クラスのプロパティを部分的にマップし、コンストラクトを使用して複雑なマップをマップするだけです。そうでなければ、あなたはこのすべてを必要としません。 – Evk

関連する問題