我在多线程环境中遇到了以下类的问题:
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 2.0,没有任何扩展,尽管我已经从NInject.Web项目中复制了NInject.Web。
我注意到在我的web服务中也出现了类似的问题。这个问题是断断续续的,很难复制。
发布于 2011-08-19 18:56:19
首先,让我说,这在许多级别上都是错误的;KernelContainer是一个基础设施类,专门用于解决ASP.NET WebForms页面生命周期中的某些限制。它从未用于应用程序代码中。使用尼尼微内核(或任何DI容器)作为服务定位器是反模式。
话虽如此,尼尼微本身绝对是线程安全的,因为它一直用于在ASP.NET中服务并行请求。不管这个NullReferenceException是从哪里来的,它几乎没有什么关系--如果有什么关系的话。
我能想到两种可能性:
KernelContainer.Kernel,并且该代码可能具有争用条件。如果在内核完全初始化之前尝试使用KernelContainer (如果您使用IKernel.Bind方法而不是按照指南加载模块),您将得到类似的错误。或者:IBar实现本身,而NullReferenceException正在DoSomething方法的某个地方发生。当您得到异常时,实际上并没有指定InjectedBar是null,所以这是一个合法的可能性。为了缩小可能性的范围,我会首先消除KernelContainer。如果由于设计不佳的遗留体系结构,您绝对必须使用尼尼微作为服务定位器,那么至少允许它创建依赖关系,而不是依赖Inject(this)。也就是说,无论哪个类或哪个类需要创建您的Foo,都要让该类调用kernel.Get<Foo>(),并将内核设置为Bind<Foo>().ToSelf()。
https://stackoverflow.com/questions/2941743
复制相似问题