3

I'm using Ninject.MVC3 with WebAPI. Originally, I was using the implementation of NinjectResolver and NinjectScope as outlined here,i.e. using _kernel.BeginBlock(), I noticed that BeginBlock() gets invoked on each call to the Controller. On load testing the controller (over several hundred invocations) I noticed that the memory consumption of w3wp increased significantly (upwards of 1.4 gigs on high load) and the GC would never reclaim any memory.

Per this SO post, the kernel should not be disposed and BeginBlock() should not be used. Following which I updated the Resolver and Scope like so:

 public class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;

    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }

    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }

    public void Dispose()
    {
        //Don't dispose the kernel
        //IDisposable disposable = (IDisposable)resolutionRoot;
        //if (disposable != null) disposable.Dispose();
        //resolutionRoot = null;
    }
}

public class NinjectResolver : NinjectScope, IDependencyResolver
 {
        private IKernel _kernel;
            public NinjectResolver(IKernel kernel): base(kernel)
            {
        _kernel = kernel;
        }
        public IDependencyScope BeginScope()
       {
          return new NinjectScope(_kernel); 
           //what's the difference between using just _kernel vs _kernel.BeginBlock()   
           //return new NinjectScope(_kernel.BeginBlock());
       }
 }

The memory consumption lowered significantly following this change(i.e. using the above implementation). I would like to understand why this is. What is it that BeginBlock() really does and when should one use it.

Is the above implementation accurate?

Community
  • 1
  • 1
Abhijeet Patel
  • 6,562
  • 8
  • 50
  • 93

1 Answers1

6

Remo Gloor says that the ActivationBlock concept is broken and that you should not use them. Furthermore, issues regarding ActivationBlock will most likely not going to be fixed, as the feature is to be removed from future Ninject versions.

The idea of Activation Blocks (current implementation) is:

  • Create exactly one instance of every type requested in the ActivationBlock
  • dispose of all instances created by the ActivationBlock when the block itself is disposed.

Also see:

Furthermore, you've tagged & named your question with "MVC3" but the System.Web.Http.Dependencies.IDependencyResolver interface you are using is related to asp.net-web-api. MVC's System.Web.Mvc.IDependencyResolver is different.

Ninject already features nuget packages which do the integration into asp.net-mvc-3 (4,5,...) and asp.net web api:

Now if you really want to implement the dependency resolver and scope yourself we can compare it to ninject's web-api implementation:

The only real difference to your code is that they have one class implementing both, IDependencyResolver and IDependencyScope and that they are consistently using the IResolutionRoot instead of the IKernel interface.

(and for comparison: MVC3 NinjectDependencyResolver.cs)

BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • Interesting. I'd still like to know whether the implementation for the Resolver and Scope above are correct. – Abhijeet Patel Nov 03 '14 at 17:44
  • the "official" ninject web-api extension is basically doing the same (see updated answer). But if possible, i would suggest going with the official ninject nuget packages instead of implemented it yourself, anyway. – BatteryBackupUnit Nov 04 '14 at 06:21
  • a)I don't see an IKernel in my code.b)The ninject nuget package is "Ninject.MVC3" hence the tag for "MVC3" – Abhijeet Patel Nov 04 '14 at 16:20
  • b) you may have installed `Ninject.MVC3` but this does not relate to `IDependencyScope` and `System.Web.Http.Dependencies.IDependencyResolver` **at all**. see [here](http://msdn.microsoft.com/en-us/library/system.web.http.dependencies.idependencyresolver%28v=vs.118%29.aspx) and [here](http://www.webadvanced.com/blog/asp.net-mvc-4-web-api-and-structuremap) – BatteryBackupUnit Nov 04 '14 at 16:34
  • Got it! I marked your answer as the solution.It looks like the Resolver and Scope defined above are correct per your comments. I'm curious though as to why this is not hooked up automatically when Ninject.MVC3 is installed. Is it because Ninject is not aware of WebApi? – Abhijeet Patel Nov 05 '14 at 16:28
  • 1
    Yes, exactly, there is actually a separate web api nuget package which i already linked in the answer: https://www.nuget.org/packages/Ninject.Web.WebApi – BatteryBackupUnit Nov 05 '14 at 19:25
  • also see chris pratt's answer [here](http://stackoverflow.com/questions/14016727/how-to-use-ninject-with-asp-net-web-api) (it's not the one marked as answer. It's a newer one!) – BatteryBackupUnit Nov 05 '14 at 19:42