AutoMapperの新バージョンで新しいIValueResolver
インターフェースを使用する方法について私は途方に暮れています。おそらく、以前のバージョンのAutoMapperでそれらを不適切に使用した可能性があります...
多くのモデルクラスがあり、それらのいくつかは、sqlmetalを使用して、複数のデータベースサーバー上の複数のデータベースから生成されます。
これらのクラスの一部には、PublicationCode
という文字列プロパティがあります。これは、サブスクリプション、オファー、インボイス、またはそれが何であるかを識別するパブリケーションを識別します。
パブリケーションは2つのシステム(古いシステムと新しいシステム)のいずれかに存在する可能性があるため、宛先モデルクラスには、パブリケーションが古いシステムと新しいシステムのどちらにあるかを示すboolプロパティがあります。
AutoMapperの古いバージョン(<5?)を使用して、PublicationCode
を入力パラメーターとして受け取り、パブリケーションの場所を示すbool
を返すValueResolver<string, bool>
を使用しました(古いシステムまたは新しいシステム)。
AutoMapperの新しいバージョン(5+?)では、これはもはや不可能のようです。新しいIValueResolverでは、src.PublicationCode
をdst.IsInNewSystem
に解決する必要があるソースモデルと宛先モデルのあらゆる組み合わせの一意の実装が必要です。
値リゾルバを間違った方法で使用しようとしていますか?もっと良い方法はありますか?リゾルバーを使用したい主な理由は、コンストラクターにサービスを挿入し、コードでDependencyResolver
などを使用する必要がないことです(Autofacを使用しています)。
現在、私は次のように使用しています:
// Class from Linq-to-SQL, non-related properties removed.
public class FindCustomerServiceSellOffers {
public string PublicationCode { get; set; }
}
これは、私が持っているいくつかのデータモデルクラスの1つで、PublicationCodeプロパティが含まれています。この特定のクラスは、このビューモデルにマップされます。
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();
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));