为什么要处理ASP.NET Web Api的依赖性解析器?
我有一个自定义IDependencyResolver
:
internal class NinjectResolver : IDependencyResolver { private IKernel _kernel; internal NinjectResolver(params ApplicationModule[] modules) { _kernel = new StandardKernel(modules); } public IDependencyScope BeginScope() { return this; } public object GetService(Type serviceType) { return _kernel.TryGet(serviceType); } public IEnumerable GetServices(Type serviceType) { return _kernel.GetAll(serviceType); } protected void Dispose(bool disposing) { if(disposing) { if(_kernel != null && !_kernel.IsDisposed) { _kernel.Dispose(); _kernel = null; } } } public void Dispose() { Dispose(true); GC.SuppresFinalize(this); } }
我正在这样注册:
public static void RegisterModules(HttpConfiguration configuration, params ApplicationModule[] modules) { _resolver = new NinjectResolver(modules); configuration.DependencyResolver = _resolver; }
一切似乎在一开始就很好。 但是,在几分钟后(参见注释 ),我的NinjectResolver
被NinjectResolver
,因此在尝试解析类型时开始抛出NullPointerException
(这是因为我在Dispose
方法中设置了_kernel = null
)。
解决此问题的一种方法是保持引用处于活动状态,并且在处理解析器时不将其设置为null。 但我为什么要这样?
我的意思是,为什么我的解析器会像这样处理,从一分钟到另一分钟? 在我的代码中没有任何地方我明确地处理它,所以它必须是Web Api框架为我做的。
注意 :有时需要几分钟,有时只需几秒钟。 这完全是随机的。
这个类被处理的原因是因为这个类有一个bug。 您正在使用NinjectResolver
作为解析器和作为作用域,并且您将NinjectResolver
实例作为IDependencyScope
返回,方法是从BeginScope()
方法返回它。 Web API基础结构为每个请求调用一次BeginScope()
方法,并且Web API将在请求结束时调用IDependencyScope.Dispose()
。 问题是你总是在发生这种情况时处理内核,这意味着在第一次请求之后你的内核将无法使用。
快速解决方法是根本不处理内核。 由于此内核将在整个应用程序的持续时间内存在,因此不处理内核通常不是问题。