まず第一に、私はすでにウェブを精査しており、解決策を探していますが、何も見つかりませんでした.
私は高度に分離されたソリューションに取り組んでおり、すべてのクラスが DI アプローチ用に設計されています (もちろん、依存関係としてインターフェイスを要求します)。MVC レイヤーで Automapper を使用して、フラット化された ViewModel でサーバー側の POCO を変換します。これまでのところ、奇妙なことは何もありません。
ViewModel の一部のプロパティは、IoC コンテナー (ninject) に登録されている一部のサービスを使用して作成する必要があり、automapper が構成されているアプリケーションの起動時には使用できないという事実によって複雑になります。タイプを解決するために使用する方法を automapper に指示するのは簡単で、ドキュメントに従って 1 行の構成のみでした。
単一のプロパティがこの動作を必要とする単純なケースでは、そのプロパティのカスタム ValueResolver を作成し、コンストラクターで依存関係を公開し、それらを使用して目的の値を返します。
問題は、たとえば、同じ動作を必要とするが出力値が異なる 20 個のプロパティがある場合に発生しますが、他のすべての ViewModel プロパティはデフォルトの「自動マッピング」で問題ありません。
オートマッパーに「これらのプロパティを解決するには、このクラスを使用してください。他のすべてのプロパティはあなたの規則を使用するだけです」と伝える方法が見つかりません。
必要なプロパティをインターフェイスに配置し、wiki で説明されているように継承マッピングを使用するなど、いくつかのアプローチを試しました。TypeConverter を使用しない限り機能しますが、これは意味がありません。DI/IoC を介して必要なサービスを取得するために TypeConverter (またはそのようなもの) が必要だからです。
例:
public interface IMyInterface
{
string MyUrl1 {get;set;}
//snip with many other urls
}
public class MyViewModel : IMyInterface
{
public string MyUrl1 {get;set;}
//snip with many other urls
public string MyAutomapperProperty1 {get;set;}
//snip with many other properties where I want to use the conventions
}
私が必要なのはこのようなものです
public class MyTypeConverter : TypeConverter<MyPoco, IMyInterface>
{
// here in the overridden method return an instance of MyViewModel
// with just the properties exposed by the interface
}
次に、オートマッパー構成で:
Automapper.CreateMap<MyPoco, IMyInterface>()
.Include<MyPoco, MyViewModel>()
.ConvertUsing<MyTypeConverter>();
Automapper.CreateMap<MyPoco, MyViewModel>();
これはうまくいきません。ConvertUsing の呼び出しを削除し、ForMember メソッドを使用してインライン マッピングを追加すると、すべてが機能し、ForMember 宣言は 2 番目のマッピングによって正しく継承されますが、ConvertUsing では継承されません。しかし、私は ForMember メソッドで DI を持つことはできません (私はアプリケーションの開始にいるため、これは静的です。さらに、これらのオブジェクトをアプリケーション レベルでインスタンス化し、それらを作成して破棄するのではなく、すべてのアプリケーションで有効にしておくことを意味します)必要な場合)。
関連するプロパティを別のオブジェクトに配置し、そのオブジェクトに直接 TypeConverter を作成して使用するという解決策があることは知っていますが、それらの POCO のリファクタリングは現在オプションではありません。継承と DI を連携させます。
読んでくれてありがとう。
更新 要求に応じて、達成したいことをより明確にしようとします。
いくつかの「サービス」があります。これらは、アプリケーション レベルではそのインターフェイスを通じてのみ認識されます。何かのようなもの:
public interface IUrlResolver { }
これは、渡したいくつかのパラメーターやその他のものに基づいて、アプリケーションに関連する URL を取得するための一連のメソッドを公開します。実装によって、他のサービス (インターフェース) などへの依存関係が公開される場合もあります。したがって、DI を使用して、IoC コンテナー リゾルバーに依存関係のチェーンを任せます。
ここで、ViewModel に 50 個のプロパティがあり、そのうち 30 個は規約に基づいた automapper のマッピングで問題なく、残りの 20 個はすべてIUrlResolverインターフェイスのさまざまな方法で解決する必要があるとします。事実を正しく理解するには:
- Application_Start (またはアプリケーションの開始によって呼び出されるいくつかの静的メソッド) で発生するため、automapper を構成する場所に DI を設定できません。
- IUrlResolverをアプリケーション レベルで解決することはできませんでした。
- 単一のプロパティに ValueResolver を使用すると、すべて問題ありません。ValueResolver コンストラクターは、オートマッパー変換が発生したときに実行時に挿入されるIUrlResolverを要求します。
- 20 個のプロパティに対して 20 個の異なる ValueResolver クラスを作成できましたが、コードが乱雑になり、大量のコードが重複し、再利用できなくなります。
- 私が欲しいのは、オブジェクトをカスタム クラス (TypeConverter など)に部分的にマップし、他のすべてのプロパティをデフォルトの規則エンジンにマップする機能です。
私が試した最も近い方法は以前に投稿したものであるため、投稿する「サンプル構文」はありません。完全に異なるアプローチが存在する場合、私は物事を分離したままにしておくことができ、別のクラスでそれらのプロパティをリファクタリングする必要がないという条件で、オープンです。