问题
I have a custom 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<object> 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);
}
}
I am registering it like this:
public static void RegisterModules(HttpConfiguration configuration, params ApplicationModule[] modules)
{
_resolver = new NinjectResolver(modules);
configuration.DependencyResolver = _resolver;
}
Everything seems to work fine at the beginning. However, after some minutes (see NOTE) my NinjectResolver
is disposed, and therefore begins to throw NullPointerException
when trying to resolve a type (this is because I am setting _kernel = null
in the Dispose
method).
A way to solve this is to keep the reference alive and not set it to null when the resolver is disposed. But why should I?
I mean, why is my resolver getting disposed just like that, from one minute to another? Nowhere in my code am I disposing it explicitly, so it must be the Web Api framework doing it for me.
NOTE: Sometimes it takes a couple of minutes, and sometimes just seconds. It's completely random.
回答1:
The reason that this class is being disposed is because there is a bug in this class. You are using the NinjectResolver
both as resolver and as scope and you are returning the NinjectResolver
instance as IDependencyScope
by returning it from the BeginScope()
method. The BeginScope()
method is called once per request by the Web API infrastructure and Web API will call IDependencyScope.Dispose()
when the request ends. The problem is that you always dispose the kernel when this happens, which means that your kernel will be unusable after the first request.
A quick fix is to just don't dispose the kernel at all. Since this kernel will live for the duration of the complete application, not disposing the kernel is typically not a problem.
来源:https://stackoverflow.com/questions/31444952/why-is-asp-net-web-apis-dependency-resolver-being-disposed