4

私がWebで見たほとんどのサンプルでは、​​MVCコントローラーのDIは次のように実行されます

public ProductController(IProductRepository Rep)
{
    this._rep = Rep;
}

カスタムControllerFactoryが使用され、選択したDIフレームワークを利用して、リポジトリが挿入されます。

上記がより良いと考えられるのはなぜですか

public ProuctController()
{
    this._rep = ObjectFactory.GetInstance<IProductRepository>();
}

これでも同じ結果が得られますが、カスタムコントローラーファクトリは必要ありません。

テストに関する限り、テストアプリは個別のBootStrapperを持つことができます。そうすれば、コントローラーがテストされているときに偽のリポジトリーを取得でき、実際に使用されているときに本物のリポジトリーを取得できます。

4

3 に答える 3

5

2番目のコンストラクターの主な欠点は、IoCコンテナーをテストごとに適切に構成する必要があることです。この設定は、コードベースが大きくなり、テストシナリオがより多様になるにつれて、実際の負担になる可能性があります。テストダブルを明示的に渡すと、一般的にテストの読み取りと保守が簡単になります。

もう1つの懸念は、膨大な数のクラスを特定のDI/IoCフレームワークに結合することです。もちろん、それを抽象化する方法はありますが、依存関係を取得するためにクラス全体にコードが散らばっています。すべての優れたフレームワークは、コンストラクターを調べることで必要な依存関係を把握できるため、多くの無駄な労力と重複したコードになります。

于 2009-06-25T15:14:37.673 に答える
5

コンストラクター インジェクション (最初のアプローチ) は、いくつかの理由でサービス ロケーター パターン (2 番目のアプローチ) より優れています。

まず、サービス ロケーターは依存関係を隠します。ProductControllers2 番目の例では、パブリック インターフェイスだけを見ても、リポジトリが必要であることを知る方法はありません。

さらに、OdeToCodeをエコーする必要があります。おもう

IProductRepository repository = Mockery.NewMock<IProductRepository>();
IProductController controller = new ProductController(repository);

よりも明確です

ObjectFactory.SetFactory(IProductRepository, new MockRepositoryFactory())
IProductController controller = new ProductController();

特に、ObjectFactory がテスト フィクスチャのSetUpメソッドで構成されている場合。

最後に、サービス ロケーター パターンは、少なくとも 1 つの特定のケースで明らかに最適ではありません。それは、自分の制御の及ばないアプリケーションを作成する人々によって消費されるコードを作成している場合です。すべてのシナリオに適用できるため、人々は一般的にコンストラクター注入 (または他の DI メソッドのいずれか) を好むと思います。すべてのケースをカバーする方法を使用してみませんか?

(Martin Fowler は、 「Inversion of Control Containers and the Dependency Injection Pattern」、特に「Service Locator vs Dependency Injection」セクションで、より徹底的な分析を提供しています)。

于 2009-06-25T15:33:36.790 に答える
4

2番目のアプローチを使用する場合、欠点は次のとおりです。

  • 巨大で読めないテストセットアップ/コンテキストメソッドが必要です
  • コンテナはコントローラに結合されています
  • もっとたくさんのコードを書く必要があります

依存性注入が必要ないのに、なぜとにかくiocコンテナを使用したいのですか?

于 2009-06-25T15:14:00.217 に答える