什么时候应该在Ninject.MVC3中使用Kernel.BeginBlock()

Abh*_*tel 3 ninject asp.net-mvc-3 asp.net-web-api

我正在使用Ninject.MVC3和WebAPI.最初,我正在使用这里概述的NinjectResolverNinjectScope的实现,即使用,我注意到每次调用Controller时都会调用BeginBlock().在对控制器进行负载测试(超过几百次调用)时,我注意到w3wp的内存消耗显着增加(高负载时高达1.4 gigs)并且GC永远不会回收任何内存._kernel.BeginBlock()

根据这篇SO帖子,不应该处理内核并且不应该使用BeginBlock().之后我更新了Resolver和Scope,如下所示:

 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());
       }
 }
Run Code Online (Sandbox Code Playgroud)

在此更改后(即使用上述实现),内存消耗显着降低.我想明白为什么会这样.什么是BeginBlock()真正做到的,什么时候应该使用它.

以上实施准确吗?

Bat*_*nit 6

雷莫格洛尔说,这个ActivationBlock概念已被打破,你不应该使用它们.此外,有关问题ActivationBlock很可能无法修复,因为该功能将从未来的Ninject版本中删除.

激活块(当前实现)的想法是:

  • 只创建一个请求的每种类型的实例ActivationBlock
  • 处理由ActivationBlock块本身处置时创建的所有实例.

另见:

此外,您已使用"MVC3"标记并命名了您的问题,但System.Web.Http.Dependencies.IDependencyResolver您使用的界面与asp.net-web-api相关.MVC System.Web.Mvc.IDependencyResolver是不同的.

Ninject已经具有nuget包,它可以集成到asp.net-mvc-3(4,5,...)和asp.net web api中:

现在,如果您真的想要自己实现依赖项解析器和范围,我们可以将它与ninject的web-api实现进行比较:

与您的代码唯一真正的区别在于它们有一个实现两者的类,IDependencyResolver并且IDependencyScope它们始终使用IResolutionRoot而不是IKernel接口.

(和用于比较:MVC3 NinjectDependencyResolver.cs)