【问题标题】:IoC and dataContext disposing in asp.net mvc 2 application在 asp.net mvc 2 应用程序中配置的 IoC 和 dataContext
【发布时间】:2010-06-01 21:51:23
【问题描述】:

我有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 创建(如果在此请求范围内没有创建任何人)。

所以现在的问题是——在哪里调用dataContext方法.Dispose()

UPD

所以我听从了 KeeperOfTheSoul 的建议并以这种方式解决了这个问题:

    public override void ReleaseController(IController controller)
    {
        base.ReleaseController(controller);

        var db = kernel.Get<DomainModel.Entities.db>();
        db.Dispose();
    }

【问题讨论】:

    标签: asp.net garbage-collection inversion-of-control


    【解决方案1】:

    处理这个问题的好地方是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】:

      有时用于处理数据库连接的模式是从终结器调用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
         }
      }
      

      【讨论】:

      • 如果您不处理非托管资源,则无需终结器。
      • 是的,在这种情况下,这可能不起作用,因为您无法在从终结器调用时释放实现 IDisposable 的类成员。如果您需要直接处置对象,Kevin Pang 的回答可能对您更有用。
      【解决方案3】:

      您可以将其挂接到 Application_EndRequest。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-24
        • 2011-03-06
        相关资源
        最近更新 更多