我觉得我错过了一些明显的东西。我已经在这里阅读了几个相关的问题,我已经阅读了Ninject维基上更新的上下文绑定页面,但是它仍然不起作用。
我正在尝试改进使用工厂模式的遗留应用程序来使用Ninject。
我有2个类(ClassB和ClassC)实现的1个接口(IInterface)。 IInterface有一个加载方法。在ClassB的加载方法中,它实例化ClassC然后执行它的加载方法。
程序流程基本上是ClassA创建ClassB并执行load方法。在加载方法中,ClassB创建了可以完成某些工作的ClassC。
我的绑定设置如此......
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>();
当它运行时,它在ClassB的加载方法中失败并出现此错误......
激活IInterface时出错没有可用的匹配绑定,且该类型不可自我绑定。
如果我尝试以下内容......
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>();
它无限循环,永远不会创建ClassC。
修改 的 我把它简化为一个单元测试,但是没有给我我想要的结果......
[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班的你好 你好,来自A班
但我想要: 来自C班的你好 B组你好 你好,来自A班
由于
答案 0 :(得分:6)
您 不 注入ClassC。您正在传递内核并直接从中解析IDoSomething。有很大的不同。
不要将内核作为参数传递 - 这样做不是依赖注入,而是服务位置(关于区别的好文章:Service Locator is an Anti-Pattern)。
将ClassC更改为:
private class ClassC
{
private IDoSomething _doSomething;
public ClassC(IDoSomething doSomething)
{
_doSomething = doSomething;
}
public void SaySomething()
{
Console.WriteLine("Hello from Class C");
//var x = _Kernel.Get<IDoSomething>();
_doSomething.SaySomething();
}
}
您还应对ClassA和ClassB进行相同的更改(传递要解析的类型/接口,而不是内核)。