我有一个使用 Ninject 作为其 DI 的应用程序。我正在添加一些新类,但它们并没有按照我认为应该的方式得到解决。
我有一个类Foo
,它实现了ISomething
接口(interface)。如果我像这样配置绑定(bind):
kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<ISomething>().To<Foo>();
然后执行:
var foo1 = kernel.Get<Foo>();
var foo2 = kernel.Get<ISomething>();
这两个变量具有 Foo
类的不同实例。
如果我将绑定(bind)更改为:
kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<ISomething>().ToMethod(ctx => ctx.Kernel.Get<Foo>());
然后执行:
var foo1 = kernel.Get<Foo>();
var foo2 = kernel.Get<ISomething>();
这两个变量具有相同实例。
我的理解是,在第一种情况下,它应该将 ISomething
解析为 Foo
,而后者又会解析为自身的单例。是我的理解有误,还是有其他问题?必须手动解决它似乎有点多余。
最佳答案
当您在注册中省略生活方式时,按照惯例,Ninject 将使用 transient 生活方式。这意味着:
kernel.Bind<ISomething>().To<Foo>();
相当于:
kernel.Bind<ISomething>().To<Foo>().InTransientScope();
加上生活方式,就更容易发现问题了:
kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<ISomething>().To<Foo>().InTransientScope();
或者更清楚:
kernel.Bind<Foo>() .To<Foo>().InSingletonScope();
kernel.Bind<ISomething>().To<Foo>().InTransientScope();
在这里您可以看到您正在将 Foo
注册为单例和 transient 。这种错误配置是一个常见的陷阱,称为 Ambiguous Lifestyles :
When multiple registrations with a different lifestyle map to the same component, the component is said to have ambiguous lifestyles. Having one single component with multiple lifestyles will cause instances of that component to be cached in different ways and this can lead to behavior that you might not expect.
某些 DI 容器确实包含可用于检测此类错误配置的验证机制,但我熟悉的所有 DI 容器都允许您以这种方式意外地错误配置容器。
关于c# - 解析接口(interface)时,Ninject 未解析为已配置的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60953235/