0

StructureMapを使用すると、次のように、慣例により名前に基づいてインスタンスを挿入できます。

Ctor:

public HomeController(IQuery getItemByProductNumberQuery, IQuery getCustomerById)

StructureMap構成:

x.For<IQuery>().Add<GetItemByProductNumberQuery>().Named("getItemByProductNumberQuery");
x.For<IQuery>().Add<GetCustomerById>().Named("getCustomerById");

私はレガシーコードを使用しているので、DIコンテナーを変更することは大変な作業ですが、目前の問題に対する他のコンテナーの解決策についても知ることは興味深いでしょう。

4

1 に答える 1

2

コードベースに抽象化が欠けているように思われます。通常の状況では、サービス(IQueryあなたの場合)は明確でなければなりませんが、あなたの状況ではそうではありません。引数名でそれらを識別すると、エラーが発生しやすくなり、DI構成を維持するのが困難になります。これは(この例で見られるように)常にこのようである必要はありませんが、おそらくあなたの場合です。

これを解決するには、IQueryインターフェースを汎用にします。

public interface IQuery<TParameters, TResult>
{
    TResult Handle(TParameters parameters);
}

これにより、このインターフェイスのすべての実装を閉じた汎用表現で登録し、制御をこの閉じた汎用表現に依存させることができます。

public HomeController(
    IQuery<GetItemByProductNumberParameters, Item> getItemQuery, 
    IQuery<GetCustomerByIdParameters, Customer> getCustomerById)

ご覧のとおり、各クエリは「XXXParameters」オブジェクトを定義します。これは、クエリの実行に必要なすべてのパラメーターを含むDTOです。のコードは次のHomeControllerようになります。

public View Item(int productNumber)
{
    var parameters = new GetItemByProductNumberParameters
    {
        ProductNumber = productNumber,
        // other parameters here
    };

    Item item = this.getItemQuery.Handle(parameters);

    return this.View(item);
}

IQuery<TParameter, TResult>StructureMapを使用してすべての実装を一度にバッチ登録するのは少し難しいかもしれませんが、このSOの質問が役立つかもしれません。そうでない場合は、別のDIコンテナを使用するとより良い結果が得られる可能性があります。

この記事でクエリをこのようにモデル化する理由の詳細については、次の記事を参照してください。一方…私のアーキテクチャのクエリ側

于 2012-09-18T11:42:49.050 に答える