私は何かが分かりにくいと感じています。私はここでいくつかの関連する質問を読みました。そして、私はNinjectのwikiの更新されたコンテキストバインディングページを読んだのですが、うまくいきません。WhenInjectedInto拡張メソッドを使用したバインドバインド
Ninjectを使用するために工場パターンを使用していたレガシーアプリケーションを改造しようとしています。
私は2つのクラス(ClassBとClassC)で実装された1つのインタフェース(IInterface)を持っています。 IInterfaceにはロードメソッドがあります。 ClassBのロードメソッドでは、ClassCをインスタンス化してからロードメソッドを実行します。
基本的に、プログラムフローはClassAでClassBを作成し、ロードメソッドを実行します。ロードメソッドでは、ClassBは何らかの作業を行うClassCを作成します。
私のバインディングが
エラーが一致するバインディングが用意されていないメソッドはIInterface活性化
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>();
これは、それがこのエラーでClassBののloadメソッドに失敗した実行さ
... ...セットアップようにしており、タイプは自己バインドできません。私は、次の...
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>();
をしようとするとそれは無限ループを実行し、決してクラスCを作成します。私はパスしたが、私が望む結果が得られていないユニットテストにこれを単純化している
EDIT ...
[TestClass]
public class NinjectTestFixture
{
private interface IDoSomething
{
void SaySomething();
}
private class ClassA : IDoSomething
{
public void SaySomething()
{
Console.WriteLine("Hello from Class A");
}
}
private class ClassB : IDoSomething
{
private IKernel _Kernel;
public ClassB(IKernel kernel)
{
_Kernel = kernel;
}
public void SaySomething()
{
Console.WriteLine("Hello from Class B");
var x = _Kernel.Get<IDoSomething>();
x.SaySomething();
}
}
private class ClassC
{
private IKernel _Kernel;
public ClassC(IKernel kernel)
{
_Kernel = kernel;
}
public void SaySomething()
{
Console.WriteLine("Hello from Class C");
var x = _Kernel.Get<IDoSomething>();
x.SaySomething();
}
}
[TestMethod]
public void TestMethod1()
{
var kernel = new StandardKernel();
kernel.Bind<IDoSomething>().To<ClassA>();
kernel.Bind<IDoSomething>().To<ClassB>().WhenInjectedInto<ClassC>();
kernel.Bind<ClassC>().ToSelf();
var x = kernel.Get<ClassC>();
x.SaySomething();
}
出力は次のとおりです。クラスC から こんにちはHelloクラスA
しかし、私は欲しい: HelloクラスC こんにちはクラスB こんにちはクラスA
おかげ
私はあなたが言っていることを理解していますが、SaySomethingメソッドでは、いくつかの作業を行うためにオブジェクトをインスタンス化する必要があります。同じクラスには、より多くの作業を行うメソッドをインスタンス化する他のメソッドがあります。私があなたが提案していることをしたなら、私のコンストラクタには約20のパラメータがあります。コードはもともと6年以上前に書かれていたので、徐々にDIを改造しようとしています。私はこれを行う方法に頭を悩まし、カーネルを通すことが最も理にかなった最も簡単な解決策でした。私はサービスの場所を探していましたが、現在のコードベースでは意味がありませんでした。 – oliwa
あなたは正しい答えです。あなたが提案した変更を加えたとき、私は期待した結果を得ました。 – oliwa
私はあなたが何を意味するのか - 私はDIを導入するために奇妙で醜い暫定的なステップを使わなければならないシステムをリファクタリングしました。 –