1

私は自分のプロジェクトで DI をかなり多く使用しており、その概念にはかなり満足していますが、よくわからない側面が 1 つあります。

したがって、私の一般的なユースケースは、コントローラーの依存関係をコンストラクターのパラメーター リストにリストする ASP.NET MVC コントローラーを使用することです。これらはコントローラーが DI コンテナーによって構築されるときに渡されます。次に、これらを読み取り専用に割り当てます。コントローラー内のアクションによって後で消費されるプライベート変数。

ここで、私の懸念は、注入された依存関係 (IMemberRepositoryとしましょう) を 1 つのアクション内でのみ使用する場合 (そして、他に 5 つのアクションがあるとしましょう)、これを ctor の依存関係としてリストする必要があるかContainer.Resolve<IMemberRepository>()、1 つのアクション内で呼び出す必要があるかです。それが使用されるアクション?

私は、すべての依存関係を ctor にリストするのが好きContainer.Resolve<>()であり、コード全体に散らばっているのが特に好きではありませんが、上記の例に進むと、DI コンテナーにインスタンス化する意味がありませんIMemberRepository。使用する!

4

3 に答える 3

3

アプリケーション コード内から Container.Resolve を呼び出さないでください。これは Service Locator パターンであり、アンチパターンと見なされます。コンストラクターを介してすべての依存関係を注入しないということは、使用されている依存関係を隠していることを意味します。これにより、クラスにどのような依存関係があるのか​​ がわかりにくくなり、そのクラスのテストが難しくなります。

依存関係が注入されているが使用されていない場合のパフォーマンスが心配ですが、オブジェクトの構築は通常非常に高速であるため、これは通常問題ではありません (構築中にこれらのオブジェクトが実行する必要があるのは、すべての着信依存関係をプライベート フィールドに格納するためです)。特定のタイプに対して構築が遅すぎることが判明した場合、その依存関係を遅延して初期化するプロキシにその依存関係をラップするなど、他の解決策があります。

クラスがあまりにも多くのコンストラクター引数を取得している場合、それは責任が多すぎることを示しています。それはやりすぎです。にフォールバックするのではなく、クラスの設計でこの欠陥を修復するようにしてくださいContainer.Resolve。たとえば、クラス ロジックを使用して依存関係のグループを単一の新しい型に抽出し、それを依存関係として注入します。

設計上の他の問題がある可能性があります。コントローラーがリポジトリの依存関係に直接依存しており、コントローラーにビジネス ロジックがある場合、抽象化が欠落しています。サービス層がありません。コマンド ハンドラークエリ ハンドラーを導入すると、適切な解決策が得られます。

于 2012-04-24T11:20:37.340 に答える
1

私はスティーブンが言ったことに賛成です。

コンストラクターの引数が多すぎる場合は、プロパティ インジェクションを選択することもできます。私はこのアプローチを支持します。何らかの理由で、まだ完全に設定されていない場合にプロパティに注入されないオブジェクトがいくつかありますが、それらはコンストラクターに注入されます。

プロパティの依存関係にガードを適用して、依存関係が null の場合に例外をスローし、それがどの依存関係であるかを認識できるようにします。

それが理にかなっていることを願っています。

于 2012-04-24T11:33:23.547 に答える
-1

それはあなたがDIで何をしたいのかによると思います。

注入された依存関係をコンストラクターのパラメーターとして使用するアプローチは、パラメーターの非常に長いリストで終わる可能性があります。
これは、注入された依存関係のメソッドをモックしたい場合がある実際のテスト駆動開発に必要な場合があります。

個人的には、DIコンテナは、アクションで必要かどうかに関係なく、常にすべての依存関係を構築する必要があるため、多くのオーバーヘッドが発生すると思います。
また、より多くの構造の使用Actionsと生産が考慮されるべきです。PartialViews

例えば

public class HomeController : Controller
{
    private IMemberRepository _memberRepo = null;

    public HomeController(IMemberRepository repo)
    {
        _memberRepo = repo;
    }

    public ActionResult Index()
    {
        MyViewModel viewModel = _memberRepo.DoSomething();
        return View(viewModel);
    }

    [ChildActionOnly]
    public PartialViewResult SomePartialAction()
    {
        return PartialView();
    }
}

ビューが部分ビューを。によってIndex.cshtml呼び出す場合。 この場合、コントローラーのコンストラクターは2回呼び出されます。アクションごとに毎回。したがって、DIコンテナも2回呼び出されます。SomePartialAction()@Html.Action("SomePartialAction")

だからそれは本当に依存します。「ハードコア」TDDの場合、コンストラクターを使用する必要があります。それ以外の場合は、必要なときに必要な場所で依存関係を解決します。

于 2012-04-24T10:41:10.783 に答える