我觉得我遗漏了一些明显的东西。我在这里阅读了几个相关问题,并且阅读了 Ninject 的 wiki 上更新的上下文绑定(bind)页面,但遗憾的是它仍然不起作用。
我正在尝试改造使用工厂模式以使用 Ninject 的遗留应用程序。
我有 1 个接口(interface) (IInterface),由 2 个类(ClassB 和 ClassC)实现。 IInterface 有一个加载方法。在 ClassB 的加载方法中,它实例化了 ClassC,然后执行它的加载方法。
基本上程序流程是ClassA创建ClassB并执行load方法。在加载方法中,ClassB 创建了一些工作的 ClassC。
我的绑定(bind)是这样设置的...
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>();
当它运行时,它在 ClassB 的加载方法中失败并出现此错误...
激活 IInterface 时出错没有可用的匹配绑定(bind),并且该类型不可自绑定(bind)。
如果我尝试以下...
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类你好
谢谢
最佳答案
您没有注入(inject) ClassC。您正在传入内核并直接从中解析 IDoSomething。有很大的不同。
不要将内核作为参数传递——这样做不是依赖注入(inject),而是服务位置(关于区别的好文章: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 进行相同的更改(传递您要解析的类型/接口(interface),而不是内核)。
关于c# - Ninject 与 WhenInjectedInto 扩展方法绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7458240/