2017-01-04 12 views
2

私はNinjectのようなフレームワークを見てきましたし、スタック上のポストは、以下のコードのような依存性注入フレームワークを使うときに自己バインドについて話しています。IoCコンテナ内の自己バインディングとは何ですか?

Bind<Samurai>().To<Samurai>(); 

彼らも、このために特別な構文を持つの範囲に行く:

Bind<Samurai>().ToSelf(); 

は、なぜあなたは自分自身にタイプをバインドしたいのでしょうか?これが役に立つ場所については実用的なアプリケーションは見当たりませんし、コードの依存関係を減らすのに役立ちます。これは単に型への参照が単にそれ自体に解決することを意味するのではないでしょうか?

+0

フレームワークで解決するオブジェクトを認識させるだけです。たとえば、 'Bind ().ToSelf()。InSingletonScope();は、型をシングルトンとして解決する必要があることをコンテナに通知します。これは、コンテナに型を登録することの一部にすぎません。 – Nkosi

+0

しかし、なぜそれを解決する必要がありますか?インスタンスをコンストラクタに渡している場合、私はそれを解決する必要はありません。 '.InSingletonScope()'も使用されているので、シングルトンパターンを自分で実装する必要はありませんか? – oflad

+0

コンテナはインスタンスをインスタンス化するものであり、どのようなタイプのインスタンスを作成して処理/処理する必要があるかを認識する必要があるためです。あなたは依存性の逆転原理を理解していますか?コンテナの全体が自分で行う必要はありません。 – Nkosi

答えて

4

依存性注入を適用して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インスタンスを返します。

関連する問題