我很惊讶地发现Ninject创建的至少一个对象在请求结束时没有被处理掉,当它被定义为InRequestScope时
这是我试图处理的对象:
接口:
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控制器工厂(这是以史蒂夫桑德森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的对象。
UPDATE:我下载了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);
}
}
和
public class EFBindingModule : NinjectModule
{
public override void Load()
{
Bind<IDataContext>().To<DataContext>().InRequestScope();
Bind<IArchivesRepository>().To<ArchivesRepository>().InRequestScope();
Bind<IMessagesRepository>().To<MessagesRepository>().InRequestScope();
}
}
其他一切都是一样的。
答案 0 :(得分:15)
一旦GC收集了请求对象,Ninject就会处理您的对象。但通常需要一些时间。但是有一种方法可以在请求结束后强行提前处理。最好的方法是使用Ninject.Web.MVC http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/而不是实现自己的ControllerFactory。另一种方法是将您的应用程序配置为使用OnePerRequestModule。