Cyn*_*hia 25 idisposable ninject entity-framework-4 asp.net-mvc-3
我很惊讶地发现Ninject创建的至少一个对象在请求结束时没有被处理掉,当它被定义为InRequestScope时
这是我试图处理的对象:
接口:
public interface IDataContext : IDisposable
{
    MessengerEntities context { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个像这样的Ninject控制器工厂(这是以史蒂夫桑德森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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
现在,当我在DataContext对象中调用context.Dispose()并运行调试器时放置一个断点,该代码永远不会被执行.
因此,证据表明Ninject在超出范围时不会处置对象,而只是创建新对象并依赖垃圾收集器在其选择时将其删除.
我的问题是:我应该关注这件事吗?因为我 - 我认为Ninject会处理任何实现IDisposable的对象.
更新:我下载了Ninject Mvc扩展(对于MVC 3),现在我正在进行MvcApplication和绑定,它似乎正在处理我的上下文对象.
在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);
    }
}
Run Code Online (Sandbox Code Playgroud)
和
public class EFBindingModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDataContext>().To<DataContext>().InRequestScope();
        Bind<IArchivesRepository>().To<ArchivesRepository>().InRequestScope();
        Bind<IMessagesRepository>().To<MessagesRepository>().InRequestScope();
    }
}
Run Code Online (Sandbox Code Playgroud)
其他一切都是一样的.
Rem*_*oor 15
一旦GC收集了请求对象,Ninject就会处理您的对象.但通常需要一些时间.但是有一种方法可以在请求结束后强行提前处理.最好的方法是使用Ninject.Web.MVC http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/,而不是实现自己的ControllerFactory.另一种方法是将应用程序配置为使用OnePerRequestModule.