web-dev-qa-db-ja.com

ninjectを使用して複数の実装を同じインターフェースにバインドする

Ninectで次のことができないのはなぜですか?

_Kernel.Bind<IPresenter>.To<DefaultPresenter>();
Kernel.Bind<IPresenter>.To<DashboardPresenter>();
Kernel.Bind<IPresenter>.To<HeartRatePresenter>();
Kernel.Bind<IPresenter>.To<GPSPresenter>();
_

4つの実装にはそれぞれ、異なる型を期待する異なるコンストラクターがあります。これを試みると、Ninjectが例外をスローし、同じインターフェイスに複数回バインドできないことを通知します。

すべてのプレゼンタークラスが継承するPresentableというクラスで、Kernel.Get<IPresenter>(new ConstructorArgument("view", this))を実行しようとしているので、ページ/ビュー内に_IPresentable Presenter_を割り当てます。プレゼンターはパラメータとして期待しています。

Ninjectがさまざまなコンストラクターパラメータータイプを認識するように、これを回避する方法は何ですか?

20
bizzehdee

複数のインターフェースへのバインディングは問題ありません。 Ninjectはこれを可能にします。ここを参照してください: https://github.com/ninject/Ninject/wiki/Multi-injection

問題は、Ninjectがコンストラクターの引数に応じて、必要な「1つ」を魔法のように提供できないことです。 Ninjectがあなたが書いたコードを使って行うように設計されているのは、Listを要求したときに、すべてのバインディングを一度に提供することです。

他の人が言ったように、単一のインスタンスだけが必要な場合、必要なのはコンテキストバインディングのように聞こえます。しかし、あなたがあなたの質問をした方法と他の答えはマルチインジェクションが不可能であるように聞こえるので少し混乱します、しかしそれが本当にあなたが望むものであるならそれは可能です。 (この場合はそうではありません)

23
Robert Noack

選択するバインディングを知る方法をninjectに指示する必要があります。

条件付きバインディングを見てください: https://github.com/ninject/ninject/wiki/Contextual-Binding

.When(...)構文の使用をお勧めしますが、.Named(...)を使用することをお勧めします(つまり、すべてのバインディングに名前/識別子を割り当て、その名前を.Get<IPresenter>("SomeName")のninjectに渡しますコール)。

11

コンテキストバインディングを使用する必要があります。私は通常、具体的な「ターゲット」クラスを使用して、カーネルが.WhenInjectedInto()または.WhenInjectecExactlyInto()を使用して提供するサービス実装を決定します。

5
cvbarros