依存性注入を適用してDependency Inversion Principleを遵守する場合、共通のアドバイスはto program to interfaces, not implementationsです。これは、コンポーネントは、コンパイル時にIWarrior
依存を取る、と私たちは、実行時にSamurai
を注入することを意味し
Bind<IWarrior>().To<Samurai>();
:時間のほとんどは、あなたが実装に抽象化から行くバインディングが表示されます理由です。
しかし、特定の条件下では、具体的なコンポーネントからそれ自身にマッピングすることが理にかなっています。つまり、「誰か」がSamurai
をリクエストした場合は、Samurai
と指定します。
最も顕著なのは、ルートタイプを解決する場合です。ルートタイプは依存関係グラフの一番上にあります。ルート型はコンテナから直接解決されます。他のすべての型は、ルート型の直接的または間接的な依存関係です。
これらのルートタイプは具体的な型によって解決されることがよくありますが、しばしばUIフレームワークを扱っています。たとえば、WebフォームPage
、MVC Controller
、Web API ApiController
などです。
ほとんどのDIコンテナは、コンクリートの未登録の型をとにかく解決することができます。これは自己バインディングが冗長であると信じさせるかもしれませんが、必ずしもそうであるとは限りません。このようなバインディングを明示的に追加すると、コンテナはそのようなバインディングの存在を知ることができます。これには、コンテナの診断機能(存在する場合)を使用してオブジェクトグラフをスキャンしてエラーを検出するという利点があります。このような機能がない場合は、通常、既知の登録を繰り返して、ユニットテストの中で何らかの検証を行うことができます。コンテナの登録が反復されたときにそのような検証が意味を持つようにするには、すべてのルートタイプをコンテナに登録する必要があります。さもなければ、この確認プロセスは偽陰性をもたらすでしょう。
DIコンテナに自己バインディングについて伝えるもう1つの理由は、コンテナが未登録の型を解決できない場合、またはコンテナのデフォルトのライフスタイルとは異なるライフスタイルで登録する必要がある場合です。型が登録されていない場合、ほとんどのコンテナはTransientインスタンスを返します。
フレームワークで解決するオブジェクトを認識させるだけです。たとえば、 'Bind().ToSelf()。InSingletonScope();は、型をシングルトンとして解決する必要があることをコンテナに通知します。これは、コンテナに型を登録することの一部にすぎません。 –
Nkosi
しかし、なぜそれを解決する必要がありますか?インスタンスをコンストラクタに渡している場合、私はそれを解決する必要はありません。 '.InSingletonScope()'も使用されているので、シングルトンパターンを自分で実装する必要はありませんか? – oflad
コンテナはインスタンスをインスタンス化するものであり、どのようなタイプのインスタンスを作成して処理/処理する必要があるかを認識する必要があるためです。あなたは依存性の逆転原理を理解していますか?コンテナの全体が自分で行う必要はありません。 – Nkosi