asp.net mvc 2应用程序中的IoC和dataContext配置

发布于 2024-09-04 00:18:02 字数 2487 浏览 8 评论 0 原文

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

I have the Global.asax like the code below:

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=***");
        }
    }
}

In this case if somewhere it is the class, defined like:

public class UserRepository : IUserRepository
{
    private db dataContext;
    private IUserGroupRepository userGroupRepository;

    public UserRepository(db dataContext, IUserGroupRepository userGroupRepository)
    {
        this.dataContext = dataContext;
        this.userGroupRepository = userGroupRepository;
    }
}

then the dataContext instance is created (if no one was created in this request scope) by Ninject.

So the trouble now is - where to invoke dataContext method .Dispose()?

UPD:

so i followed the advice from KeeperOfTheSoul and solved the issue in such way:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

熟人话多 2024-09-11 00:18:02

处理此问题的好地方是 IControllerFactory.ReleaseController,例如

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

在 NInject 中,这可以通过使用 激活块,在创建控制器时请求开始时您可以将激活块存储在HttpContext的当前项中,在ReleaseController期间您可以检索之前创建的激活块并将其丢弃。

您还可以考虑使用 InScope 并让自定义范围实现 INotifyWhenDispose。之后的用法与激活块相同,只不过现在您将范围存储在 HttpContext 的当前项中。

A good place to handle this is in IControllerFactory.ReleaseController, eg

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

In NInject this could be handled by scoping using an activation block, at the start of the request when creating the controller you can store the activation block in the HttpContext's current items, during ReleaseController you can retrieve the previously created activation block and dispose it.

You could also consider using InScope and having the custom scope implement INotifyWhenDisposed. After that the usage is the same as with an activation block, except now you store the scope in the HttpContext's current items.

红墙和绿瓦 2024-09-11 00:18:02

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

A pattern that is sometimes used to dispose db connections is to call Dispose from the finaliser.

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
   }
}
迷爱 2024-09-11 00:18:02

您可以将其挂接到 Application_EndRequest 中。

You could hook it into Application_EndRequest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文