Why is ASP.NET Web Api Dependency Resolver available?

I have a custom one 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 register it like this:

public static void RegisterModules(HttpConfiguration configuration, params ApplicationModule[] modules)
{
     _resolver = new NinjectResolver(modules);
     configuration.DependencyResolver = _resolver;
}

      

Everything seems to be working fine. However, after a few minutes (see NOTE ) mine NinjectResolver

is located and therefore starts throwing NullPointerException

when trying to resolve the type (this is because I am setting _kernel = null

in Dispose

).

The way to work around the problem is to keep the reference in memory and not set it to zero when placing the resolver. But why should I?

I mean, why is my resolver so easy to figure out any minute? Nowhere in my code do I control it explicitly, so for me it should be a Web Api framework.

NOTE . Sometimes it takes a couple of minutes, sometimes it takes seconds. This is completely random.

+3


source to share


1 answer


The reason this class is found is because there is a bug in this class. You use NinjectResolver

both as a converter and as a scope, and you return an instance NinjectResolver

as IDependencyScope

by returning it from a method BeginScope()

. The method BeginScope()

is called once for each request by the web API framework, and the web API is called IDependencyScope.Dispose()

when the request ends. The problem is that you always remove the kernel when this happens, which means your kernel will be unusable after the first request.



The quick fix is ​​to just not use the kernel at all. Since this kernel will live for the entire application, it is usually not a problem not to dispose of the kernel.

+5


source







All Articles