Multithreading NInject和线程安全
我在多线程环境中遇到以下类的问题:Multithreading NInject和线程安全,multithreading,ninject,Multithreading,Ninject,我在多线程环境中遇到以下类的问题: public class Foo { [Inject] public IBar InjectedBar { get; set; } public bool NonInjectedProp { get; set; } public void DoSomething() { /* The following line is causing a null-reference exception */
public class Foo
{
[Inject]
public IBar InjectedBar { get; set; }
public bool NonInjectedProp { get; set; }
public void DoSomething()
{
/* The following line is causing a null-reference exception */
InjectedBar.DoSomething();
}
public Foo(bool nonInjectedProp)
{
/* This line should inject the InjectedBar property */
KernelContainer.Inject(this);
NonInjectedProp = nonInjectedProp;
}
}
这是一个遗留类,这就是为什么我使用属性而不是构造函数注入
有时调用DoSomething()时,InjectedBar属性为null。在单线程应用程序中,一切运行正常
这是怎么发生的?我该如何预防
虽然我从NInject.Web项目复制了KernelContainer,但我使用的是没有任何扩展的NInject 2.0
我注意到在我的web服务中也出现了类似的问题。这个问题是非常间歇性的,很难复制。首先,让我说,这在很多层面上都是错误的;
KernelContainer
是一个专门用于解决ASP.NET WebForms页面生命周期中某些限制的基础结构类。它从来没有打算在应用程序代码中使用。使用Ninject内核(或任何DI容器)作为服务定位器
也就是说,Ninject本身绝对是线程安全的,因为它一直用于ASP.NET中的并行请求服务。无论这个NullReferenceException
来自何处,它与Ninject几乎没有任何关系
我可以想到两种可能性:
KernelContainer.Kernel
,并且该代码可能具有竞争条件。如果在内核完全初始化之前有人试图使用KernelContainer
(如果您使用IKernel.Bind
方法而不是按照指南加载模块,则可能会出现这样的错误。或:IBar
实现本身,而NullReferenceException
发生在DoSomething
方法内部的某个地方。当您获得异常时,实际上并没有指定InjectedBar
为null
,因此这是一种合理的可能性为了缩小可能性范围,我首先要消除
KernelContainer
。如果由于设计糟糕的遗留体系结构而必须将Ninject用作服务定位器,那么至少允许它创建依赖项,而不是依赖Inject(this)
。也就是说,无论哪个类或哪个类需要创建Foo
,都要调用kernel.Get()
,并将内核设置为Bind().ToSelf()
您的环境是什么?i、 例如,您是否在WCF中托管?什么版本的ninject?你在使用什么扩展项目?你能在单元测试中复制吗?NInject 2.0,没有扩展。KernelContainer与NInject.Web中的相同。