代码之家  ›  专栏  ›  技术社区  ›  zerkms

ASP.NET MVC 2应用程序中的IOC和DataContext处理

  •  2
  • zerkms  · 技术社区  · 15 年前

    我有 Global.asax 如下面的代码:

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
        // ....
        }
    
        protected void Application_Start()
        {
        AreaRegistration.RegisterAllAreas();
    
        RegisterRoutes(RouteTable.Routes);
    
        ControllerBuilder.Current.SetControllerFactory(typeof(IOCControllerFactory));
        }
    }
    
    public class IOCControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel kernel;
    
        public IOCControllerFactory()
        {
            kernel = new StandardKernel(new NanocrmContainer());
        }
    
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
                return base.GetControllerInstance(requestContext, controllerType);
    
            var controller = kernel.TryGet(controllerType) as IController;
    
            if (controller == null)
                return base.GetControllerInstance(requestContext, controllerType);
    
            var standartController = controller as Controller;
    
            if (standartController is IIoCController)
                ((IIoCController)standartController).SetIoc(kernel);
    
            return standartController;
        }
    
        class NanocrmContainer : Ninject.Modules.NinjectModule
        {
            public override void Load()
            {
                // ...
    
                Bind<DomainModel.Entities.db>().ToSelf().InRequestScope().WithConstructorArgument("connection", "Data Source=lims;Initial Catalog=nanocrm;Persist Security Info=True;User ID=***;Password=***");
            }
        }
    }
    

    在这种情况下,如果它在某个地方是类,则定义如下:

    public class UserRepository : IUserRepository
    {
        private db dataContext;
        private IUserGroupRepository userGroupRepository;
    
        public UserRepository(db dataContext, IUserGroupRepository userGroupRepository)
        {
            this.dataContext = dataContext;
            this.userGroupRepository = userGroupRepository;
        }
    }
    

    然后 dataContext 实例由ninject创建(如果在此请求范围中没有创建任何人)。

    所以现在的问题是-在哪里调用 数据文本 方法 .Dispose() ?

    UPD :

    所以我听从了 止咳糖浆 解决了这个问题:

        public override void ReleaseController(IController controller)
        {
            base.ReleaseController(controller);
    
            var db = kernel.Get<DomainModel.Entities.db>();
            db.Dispose();
        }
    
    3 回复  |  直到 15 年前
        1
  •  3
  •   Chris Chilvers    15 年前

    处理这个的好地方在 IControllerFactory.ReleaseController

    public override void ReleaseController() {
        base.ReleaseController();
        //Do whatever you need to clean up the IoC container here
    }
    

    在ninject中,可以通过使用 activation block ,在创建控制器时,在请求开始时,可以将激活块存储在httpcontext的当前项中,在ReleaseController期间,可以检索先前创建的激活块并对其进行处置。

    你也可以考虑使用 InScope 并具有自定义范围实现 INotifyWhenDisposed . 之后的用法与激活块的用法相同,只是现在将作用域存储在httpcontext的当前项中。

        2
  •  2
  •   Igor Zevaka    15 年前

    有时用于处理数据库连接的模式是调用 Dispose 来自决赛选手。

    public class db : IDisposable {
       //called by the garbage collector 
       ~db() {
         //Call dispose to make sure the resources are cleaned up
         Dispose(false);
       }
    
       //IDisposable implementation
       public void Dispose() {
         Dispose(true);
       }
       //subclasses of db can override Dispose(bool) and clean up their own fields
       protected virtual void Dispose (bool disposing) {
         if (disposing) {
           //Supress finalization as all resources are released by this method
           //Calling Dispose on IDisposable members should be done here
           GC.SupressFinalize();
         }
         //Clean up unmanaged resources
         //Do not call other objects as they might be already collected if called from the finalizer
       }
    }
    
        3
  •  1
  •   Kevin Pang    15 年前

    您可以将其挂接到应用程序的endrequest中。