web-dev-qa-db-ja.com

依存性注入(DI)と制御の反転(IoC)コンテナーを使用したコンポジションルートの許容可能な配置

IoCコンテナーのコンポジションルートの適切な配置がアプリケーションのエントリポイントに可能な限り近い方法について、 Mark Seemannの「Ploeh」ブログ を含むいくつかのソースを読みました。

.NETの世界では、これらのアプリケーションは一般に、Webプロジェクト、WPFプロジェクト、コンソールアプリケーション、典型的なUI(読み取り:ライブラリプロジェクトではない)と考えられているようです。

それがライブラリプロジェクトのグループの論理的なエントリポイントを表し、このようなプロジェクトグループのクライアントが他の誰かの仕事である場合、コンポジションルートをライブラリプロジェクトのエントリポイントに配置することは、この賢明なアドバイスに本当に反していますか? 、その作者がコンポジションルートをプロジェクト(UIプロジェクトまたはさらに別のライブラリプロジェクト)に追加できない、または追加しない人はいますか?

私はIoCコンテナー実装としてNinjectに精通していますが、必要なすべてのバインディング構成を含むモジュールをスキャンできるという点で、他の多くも同じように機能すると思います。これは、バインディングモジュールを独自のライブラリプロジェクトに配置して、メインライブラリプロジェクトの出力でコンパイルできることを意味します。クライアントが構成を変更したい場合(私のケースではありえないシナリオ)、置換DLLをドロップして、バインディングモジュールを含むライブラリ。

これにより、最も一般的なクライアントが依存関係の注入とコンポジションのルートを処理する必要がなくなり、ライブラリプロジェクトグループのAPIが最もクリーンになります。

しかし、これは問題に関する従来の知恵に直面して飛ぶようです。他の人が使用するためにライブラリを開発しているだけではなく、開発者がUIプロジェクトの開発にもある程度の調整をしていると仮定しているだけですか?

8
Jeff

あなたのバインディングモジュールアプローチは最良のソリューションです。クライアントが構成を変更する可能性が低い場合は、特にライブラリのDIの使用に問題があります。

一般向けにリリースするライブラリを作成したい場合、クライアントが現時点で好む特定のDIシステムの複雑さや厳格さに対処したくないでしょう。ライブラリは、多くの依存関係や広範なトレーニングなしで使用できる下位レベルのコンポーネントである場合に最適です。選択したDIシステムは時間とともに変化し、クライアントアプリケーションとの互換性がなくなる可能性があります。

2
Frank Hileman

ライブラリは、クリーンなドメイン固有のAPIを備えたブラックボックスであると想定されています。クライアントにリークせず、何らかの方法でクライアントを制約しない限り、DIを含むライブラリ内で必要なツールやパターンを使用しても問題はありません。

拡張性やライブラリ構成の変更を提供する必要がある場合でも、ライブラリとクライアント間で単一のコンポジションルートを共有しなくても実行できます。

ライブラリにDIを実装するためだけに別のサードパーティライブラリにライブラリを正当化できるかどうかは別の問題ですが、DIパターン自体は依存関係なしで実装できることに注意してください。

2
astreltsov