2016-07-11 3 views
15

新しいバージョンのAutoMapperで新しいIValueResolverインターフェイスを使用する方法については紛失しています。おそらく私は以前のバージョンのAutoMapperでそれらを不適切に使用していました...AutoMapperの新しいIValueResolverの使い方は?

私はモデルクラスがたくさんありますが、それらの中にはsqlmetalを使用していくつかのデータベースサーバーのいくつかのデータベースから生成されるものがあります。

これらのクラスの中には、サブスクリプション、オファーまたは請求書などが属するパブリケーションを識別する文字列プロパティPublicationCodeがあります。

パブリケーションは2つのシステム(古いシステムと新しいシステム)のどちらかに存在することができるため、パブリケーションが古いシステムにあるか新しいシステムにあるかを示す宛先モデルクラスにboolプロパティがあります。 AutoMapperの古いバージョン(< 5?)を使用して

は、Iは入力パラメータとしてPublicationCodeを取っValueResolver<string, bool>を用い、そして出版(新旧システム)の位置を示すboolを返さ。

AutoMapperの新しいバージョン(5+?)ではこれはもう不可能に思えます。新しいIValueResolverは、私が持っているソースモデルとデスティネーションモデルのそれぞれの組み合わせを一意に実装する必要があります。src.PublicationCodedst.IsInNewSystemに解決する必要があります。

私はちょうど間違った方法で値リゾルバを使用しようとしていますか?より良い方法がありますか?私がリゾルバを使用したい主な理由は、コンストラクタにサービスを注入し、コードにDependencyResolverなどを使用する必要がないことです(私はAutofacを使用しています)。

現在、私は次のようにそれを使用する:

// Class from Linq-to-SQL, non-related properties removed. 
public class FindCustomerServiceSellOffers { 
    public string PublicationCode { get; set; } 
} 

はこれが)PublicationCodeプロパティが含まれて、私が持っているいくつかのデータモデルクラスの1つです。この特定のクラスは、このビューモデルにマッピングされている:

public class SalesPitchViewModel { 
    public bool IsInNewSystem { get; set; } 
} 

この2つのクラスのマッピングの定義(式がIProfileExpressionである)であり、非関連マッピングは除去:

expression.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>() 
      .ForMember(d => d.IsInNewSystem, o => o.ResolveUsing<PublicationSystemResolver>().FromMember(s => s.PublicationCode)); 

とレゾルバを:

public class PublicationSystemResolver : ValueResolver<string, bool> 
{ 
    private readonly PublicationService _publicationService; 
    public PublicationSystemResolver(PublicationService publicationService) 
    { 
     _publicationService = publicationService; 
    } 

    protected override bool ResolveCore(string publicationCode) 
    { 
     return _publicationService.IsInNewSystem(publicationCode); 
    } 
} 

そしてマッパーの使用:

var result = context.FindCustomerServiceSellOffers.Where(o => someCriteria).Select(_mapper.Map<SalesPitchViewModel>).ToList(); 
+0

完了しました。 AutoMapperの現在の使い方を示すために、やや簡潔なコードを追加しました。 – PaddySe

答えて

5

さらに一般的な値リゾルバを作成するには、IMemberValueResolver<object, object, string, bool>を実装し、マッピング設定でそれを使用します。以前と同じようにソースプロパティ解決関数を提供することができます。

public class PublicationSystemResolver : IMemberValueResolver<object, object, string, bool> 
{ 
    private readonly PublicationService _publicationService; 

    public PublicationSystemResolver(PublicationService publicationService) 
    { 
     this._publicationService = publicationService; 
    } 

    public bool Resolve(object source, object destination, string sourceMember, bool destMember, ResolutionContext context) 
    { 
     return _publicationService.IsInNewSystem(sourceMember); 
    } 
} 



cfg.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>() 
    .ForMember(dest => dest.IsInNewSystem, 
     src => src.ResolveUsing<PublicationSystemResolver, string>(s => s.PublicationCode)); 
+0

完全に動作するdotnetfiddleを構築しようとしていますが、AutoMapperのnugetパッケージが好きではありません – Rhumborl

+0

ああ、すごい、そのインターフェースは見えませんでした。私はすべてのレゾルバについてあなたの提案を実装しましたが、今はop_Equalityに関するいくつかの奇妙な例外がありますが、AutoMapperのアップグレードに関連していると思いますが、おそらくこの特定の質問には関係しません。ご助力ありがとうございます!! – PaddySe

+0

@Rhumborl私はあなたの答えと全く同じことをしましたが、私のリゾルバークラスは決してブレークポイントに当たっていませんでした。何か案が?あなたがそれを調べたいなら、私はレポを作成することができます。ありがとう。 – Robin

関連する問題