entity-framework-4 - 超出范围时,Ninject 不会对对象调用 Dispose

标签 entity-framework-4 asp.net-mvc-3 ninject idisposable

我惊讶地发现,当它被定义为 InRequestScope 时,至少有一个由 Ninject 创建的对象在请求结束时没有被处理掉

这是我要处理的对象:

界面:

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

MessengerEntities 是 Entity Framework 对 ObjectContext 的实现——我的上下文对象。

然后我创建一个像这样的具体类:
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 Controller 工厂(这是仿照 Steve Sanderson MVC 2 书):
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();
        }
    }
}

现在,当我在 DataContext 对象中对 context.Dispose() 的调用设置断点并运行调试器时,该代码永远不会被执行。

因此,有证据表明,Ninject 不会在对象超出范围时处理它们,而是简单地创建新对象并依赖垃圾收集器在其选择的时间处理它们。

我的问题是:我应该担心这个吗?因为我——我认为 Ninject 会处理任何实现 IDisposable 的对象。

更新:我下载了 Ninject Mvc 扩展(适用于 MVC 3),这就是我现在执行 MvcApplication 和绑定(bind)的方式,它似乎正在处理我的上下文对象。

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

其他一切都保持不变。

最佳答案

Ninject 将在 GC 收集到请求对象后立即处理您的对象。但通常这需要一些时间。但是有一种方法可以在请求结束后强制提前处理。最好的方法是使用 Ninject.Web.MVC http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/而不是实现自己的 ControllerFactory。另一种方法是将应用程序配置为使用 OnePerRequestModule。

关于entity-framework-4 - 超出范围时,Ninject 不会对对象调用 Dispose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5145775/

相关文章:

c# - Entity Framework 超时

entity-framework - 文本转换和查找实体复数(集合)

asp.net-mvc-3 - ASP.NET MVC3 - 带有 @Html.EditorFor 的文本区域

ninject - 如何在 mvc 站点的类项目部分中初始化 Ninject

c# - 从 WCF 服务操作返回 EF4 POCO 时引发 CommunicationException

entity-framework-4 - 如何在 Entity Framework Code First 中指定复合键

asp.net-mvc-3 - 注册后根据角色重定向

jquery - 使用 jQuery 独立 Web 应用程序与服务器端演示框架

asp.net-mvc - 如何避免存储库重复代码

c# - Ninject 特定于构造函数的代码顺序