3

據我所知,DependencyResolver是線程安全的,但是,運行以下代碼會在後臺線程中拋出一個空引用異常。Unity MVC GetService在後臺線程拋出NullReferenceException

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() 

我知道,「服務定位器」模式是反模式。在這一點上,我只是想明白爲什麼這不起作用。

任何見解,將不勝感激。

謝謝!

+0

發現這個:http://www.prowareness.com/blog/tag/nullreferenceexception/所以顯然asp.net mvc依賴於HttpContext.Current,這就是爲什麼這不是在我的MVC應用程序工作。 – Adam

回答

5

從堆棧跟蹤中可以明顯看出,您使用的是NuGet軟件包,它是一些非官方軟件包,並且不是由Microsoft發佈的。這個軟件包包含一個錯誤。其UnityDependencyResolver.ChildContainer屬性調用HttpContext.Current.Items而不檢查HttpContext.Current是否爲空,並且當實例在Web請求的上下文之外解析時導致NullReferenceException

因此,我認爲你最好使用official NuGet package,而不是使用非官方的NuGet包。

+0

+1針對調用'System.Web.MVC.ViewEngines'的'async' MVC 5方法修復了我的問題,該方法又使用Unity來注入它的依賴關係。使用Unity.MVC4和Unity.MVC5重現了.NET4.6.2中的錯誤。轉移到Unity.MVC(官方微軟包)解決了這個問題,只需要命名空間的變化。 –

相關問題