Ninject不调用Dispose对象时超出范围 [英] Ninject doesn't call Dispose on objects when out of scope

查看:204
本文介绍了Ninject不调用Dispose对象时超出范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很惊讶地发现,由Ninject创建我的对象中的至少一个不是在请求结束时,它已被定义为InRequestScope处置

I was surprised to find that at least one of my objects created by Ninject is not disposed of at the end of the request, when it has been defined to be InRequestScope

下面是我试图处置对象:

Here's the object I'm trying to dispose:

接口:

public interface IDataContext : IDisposable
{
    MessengerEntities context { get; set; }
}

MessengerEntities是实体框架的ObjectContext的实现的 - 我的上下文对象

MessengerEntities is Entity Framework's implementation of ObjectContext -- my context object.

然后,我创建一个具体的类,像这样:

Then I create a concrete class like so:

public class DataContext : IDataContext
{
    private MessengerEntities _context = new MessengerEntities();
    public MessengerEntities context
    {
        get
        {
            return _context;
        }
        set
        {
            _context = value;
        }
    }
    #region IDisposable Members

    public void Dispose()
    {
        context.Dispose();
    }

    #endregion
}

然后,我有一个Ninject控制器工厂,像这样(这是仿照史蒂夫·桑德森MVC 2册):

And then I have a Ninject controller factory like so (this is modeled on the Steve Sanderson MVC 2 book):

public class NinjectControllerFactory : DefaultControllerFactory
{
    // a Ninject "kernel" is the thing that can supply object instances
    private IKernel kernel = new StandardKernel(new MessengerServices());

    // ASP.NET MVC calls this to get the controller for each request
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return null;
        return (IController)kernel.Get(controllerType);
    }

    private class MessengerServices : NinjectModule
    {
        public override void Load()
        {
            Bind<IDataContext>().To<DataContext>().InRequestScope();
            Bind<IArchivesRepository>().To<ArchivesRepository>().InRequestScope();
            Bind<IMessagesRepository>().To<MessagesRepository>().InRequestScope();
        }
    }
}

现在,当我把一个断点调用context.Dispose()在DataContext对象和运行调试器,即code永远不会被执行。

Now, when I put a breakpoint at the call to context.Dispose() in the DataContext object and run the debugger, that code never gets executed.

所以,有证据表明,Ninject不会释放对象,当他们走出去的范围,而只是在其选定的时间创造了新的对象,并依赖于垃圾收集摆脱他们。

So, the evidence suggests that Ninject does not dispose of objects when they go out of scope, but simply creates new objects and relies on the garbage collector to get rid of them at a time of its choosing.

我的问题是:我应该关心这个?因为我 - 我想Ninject会处理的实现IDisposable任何对象的

My question is: should I be concerned about this? Because I am -- I would think Ninject would dispose of any object that implements IDisposable.

更新:我下载了Ninject的mvc扩展名(MVC 3),这是现在我怎样,我做MvcApplication和绑定,它似乎被我的配置上下文对象。

UPDATE: I downloaded the Ninject Mvc extensions (for MVC 3) and this is now how I'm doing the MvcApplication and the binding, and it does seem to be disposing of my context object.

在Global.asax的:

In global.asax:

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

    protected override Ninject.IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        return kernel;
    }

    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }
}

public class EFBindingModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDataContext>().To<DataContext>().InRequestScope();
        Bind<IArchivesRepository>().To<ArchivesRepository>().InRequestScope();
        Bind<IMessagesRepository>().To<MessagesRepository>().InRequestScope();
    }
}

其他一切保持不变。

Everything else remains the same.

推荐答案

Ninject将尽快请求对象是由GC收集处理你的对象。但通常这需要一些时间。但是有一个办法迫使早处置的要求结束之后。最好的办法是使用Ninject.Web.MVC <一个href=\"http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/\">http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/而不是实现自己的ControllerFactory。另一种方法是配置您的应用程序使用OnePerRequestModule。

Ninject will dispose your objects as soon as the request object is collected by the GC. But normally this takes some time. But there is a way to force early disposal after the request ended. The best way is to use Ninject.Web.MVC http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ instead of implementing your own ControllerFactory. The other way is to configure your application to use the OnePerRequestModule.

这篇关于Ninject不调用Dispose对象时超出范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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