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

Asp.net mvc 3 什么时候应该在Ninject.MVC3中使用Kernel.BeginBlock(),asp.net-mvc-3,asp.net-web-api,ninject,Asp.net Mvc 3,Asp.net Web Api,Ninject,我将Ninject.MVC3与WebAPI一起使用。 最初,我使用的是所概述的NinjectResolver和NinjectScope的实现,即使用\u kernel.BeginBlock(), 我注意到每次调用控制器时都会调用BeginBlock()。在对控制器进行负载测试(超过几百次调用)时,我注意到w3wp的内存消耗显著增加(高负载时高达1.4G),并且GC永远不会回收任何内存 根据,内核不应被处置,并且BeginBlock()不应被使用。接下来,我更新了解析器和作用域,如下所示: pu

我将Ninject.MVC3与WebAPI一起使用。 最初,我使用的是所概述的NinjectResolverNinjectScope的实现,即使用
\u kernel.BeginBlock()
, 我注意到每次调用控制器时都会调用BeginBlock()。在对控制器进行负载测试(超过几百次调用)时,我注意到w3wp的内存消耗显著增加(高负载时高达1.4G),并且GC永远不会回收任何内存

根据,内核不应被处置,并且BeginBlock()不应被使用。接下来,我更新了解析器和作用域,如下所示:

 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());
       }
 }
public类NinjectScope:IDependencyScope
{
受保护的IResolutionRoot resolutionRoot;
公共NinjectScope(IResolutionRoot内核)
{
resolutionRoot=内核;
}
公共对象GetService(类型serviceType)
{
IRequest request=resolutionRoot.CreateRequest(serviceType,null,新参数[0],true,true);
返回resolutionRoot.Resolve(请求).SingleOrDefault();
}
公共IEnumerable GetServices(类型serviceType)
{
IRequest request=resolutionRoot.CreateRequest(serviceType,null,新参数[0],true,true);
返回resolutionRoot.Resolve(request.ToList();
}
公共空间处置()
{
//不要处理内核
//IDisposable一次性=(IDisposable)resolutionRoot;
//if(disposable!=null)Dispose.Dispose();
//resolutionRoot=null;
}
}
公共类NinjectResolver:NinjectScope,IDependencyResolver
{
私有IKernel_内核;
公共NinjectResolver(IKernel内核):基本(内核)
{
_内核=内核;
}
公共IDependencyScope BeginScope()
{
返回新的NinjectScope(_内核);
//只使用_kernel和_kernel.BeginBlock()有什么区别
//返回新的NinjectScope(_kernel.BeginBlock());
}
}
在此更改后(即使用上述实现),内存消耗显著降低。我想了解这是为什么。 BeginBlock()真正做的是什么?应该在什么时候使用它


上述实现是否准确?

Remo-Gloor表示,
ActivationBlock
概念已被打破,您不应使用它们。此外,与
ActivationBlock
有关的问题很可能不会得到解决,因为该功能将从未来的Ninject版本中删除

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

  • 激活块中请求的每种类型创建一个实例
  • 当释放块本身时,释放由激活块创建的所有实例
另见:

此外,您已经用“MVC3”标记并命名了您的问题,但您使用的接口与asp.net-web-api相关。MVC是不同的

Ninject已经提供了nuget软件包,这些软件包可以集成到asp.net-mvc-3(4,5,…)和asp.net web api中:

现在,如果您真的想自己实现依赖项解析器和作用域,我们可以将其与ninject的web api实现进行比较:

  • 继承自
代码的唯一真正区别在于,它们有一个类同时实现了
idependencysolver
IDependencyScope
,并且它们始终使用
IResolutionRoot
而不是
IKernel
接口


(作为比较:)

很有趣。我仍然想知道上述解析器和作用域的实现是否正确。“官方”ninject web api扩展基本上也是这样做的(请参阅更新的答案)。但是如果可能的话,我建议使用官方的ninject nuget包,而不是自己实现它。a)我在代码中没有看到IKernel。b)ninject nuget包是“ninject.MVC3”,因此标记为“MVC3”b) 您可能已经安装了
Ninject.MVC3
,但这与
IDependencyScope
System.Web.Http.Dependencies.idependencysolver
完全无关。请看,是的,确切地说,实际上有一个单独的web api nuget包,我已经在答案中链接了它: