什么时候应该在Ninject.MVC3中使用Kernel.BeginBlock() [英] When should one use Kernel.BeginBlock() in Ninject.MVC3

查看:91
本文介绍了什么时候应该在Ninject.MVC3中使用Kernel.BeginBlock()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Ninject.MVC3与WebAPI一起使用. 最初,我使用的是 NinjectResolver NinjectScope 的实现,如

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.

根据此SO帖子,内核不应是不得使用 BeginBlock().接下来,我像这样更新了Resolver和Scope:

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());
       }
 }

此更改后(即使用上述实现),内存消耗显着降低.我想知道为什么会这样. 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.

以上实施方式准确吗?

推荐答案

Remo Gloor说ActivationBlock概念已损坏,您不应使用它们.此外,关于ActivationBlock的问题很可能不会得到解决,因为该功能将从将来的Ninject版本中删除.

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:

  • ActivationBlock
  • 中创建所请求的每种类型的恰好一个实例
  • 处置块本身放置后由ActivationBlock创建的所有实例.
  • 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.

另请参阅:

  • https://github.com/ninject/ninject/issues/106
  • Future of Activation Blocks

此外,您已标记&用"MVC3"命名您的问题,但 System.Web.Http.Dependencies.IDependencyResolver 接口与asp.net-web-api有关. MVC的 System.Web.Mvc.IDependencyResolver 不同.

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已经具有nuget软件包,它们可以集成到asp.net-mvc-3(4,5,...)和asp.net Web api中:

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

  • Ninject.MVC3
  • WebApi

现在,如果您真的想实现依赖关系解析器并自己确定范围,我们可以将其与ninject的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:

  • NinjectDependencyResolver.cs
  • which inherits from NinjectDependencyScope.cs

与您的代码唯一的真正区别是,它们具有一个同时实现IDependencyResolverIDependencyScope的类,并且它们始终使用IResolutionRoot而不是IKernel接口.

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.

(进行比较: 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆