Unity中的MVC在后台线程中使用GetService会抛出NullReferenceException异常。

3
据我所知,DependencyResolver是线程安全的。然而,在后台线程中运行以下代码会抛出空引用异常。
public interface ITest {

}
public class Test : ITest {

}

//this works fine
var service = DependencyResolver.Current.GetService<ITest>();

var t1 = Task.Run(() => {
   //This throws a Null Reference exception.
   // note that DependencyResolver.Current is NOT null.  
   // The exception occurs in GetService
   var s1 = DependencyResolver.Current.GetService<ITest>();
});
Task.WaitAll(t1);

以下是堆栈跟踪信息:

at Unity.Mvc4.UnityDependencyResolver.get_ChildContainer()
at Unity.Mvc4.UnityDependencyResolver.IsRegistered(Type typeToCheck)
at Unity.Mvc4.UnityDependencyResolver.GetService(Type serviceType)
at System.Web.Mvc.DependencyResolverExtensions.GetService[TService](IDependencyResolver resolver)
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()

我知道“服务定位器”模式是一种反模式。目前,我只是想理解为什么这种方式行不通。
欢迎提供任何见解。
谢谢!

发现了这个链接:http://www.prowareness.com/blog/tag/nullreferenceexception/ 显然,asp.net mvc 依赖于HttpContext.Current,这就是为什么在我的MVC应用程序中无法正常工作的原因。 - Adam
1个回答

6
从堆栈跟踪可以看出,您正在使用Unity.Mvc4 NuGet包,这是一些非官方的包,不是由Microsoft发布的。该软件包包含一个错误。其UnityDependencyResolver.ChildContainer属性调用HttpContext.Current.Items而不检查HttpContext.Current是否为空,并且在Web请求上下文之外解析实例时会引发NullReferenceException异常。
因此,我认为您最好使用官方NuGet包,而不是使用那个非官方的NuGet包。

对我来说解决了一个问题,这个问题是关于一个调用了System.Web.MVC.ViewEngines的异步MVC 5方法,而该方法又使用Unity来注入其依赖项。在.NET4.6.2中使用Unity.MVC4和Unity.MVC5重现了这个错误。转而使用Unity.MVC(官方Microsoft包)解决了这个问题,并且只需要进行命名空间更改即可。 - Dr Rob Lang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接