国际奥委会和处置的DataContext在asp.net MVC 2的应用 [英] IoC and dataContext disposing in asp.net mvc 2 application

查看:154
本文介绍了国际奥委会和处置的DataContext在asp.net MVC 2的应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有的Global.asax 像code如下:

 公共类MvcApplication:System.Web.HttpApplication
{
    公共静态无效的RegisterRoutes(RouteCollection路线)
    {
    // ....
    }    保护无效的Application_Start()
    {
    AreaRegistration.RegisterAllAreas();    的RegisterRoutes(RouteTable.Routes);    ControllerBuilder.Current.SetControllerFactory(typeof运算(IOCControllerFactory));
    }
}公共类IOCControllerFactory:DefaultControllerFactory
{
    私人只读的iKernel内核;    公共IOCControllerFactory()
    {
        内核=新StandardKernel(新NanocrmContainer());
    }    保护覆盖一个IController GetControllerInstance(RequestContext的RequestContext的,类型controllerType)
    {
        如果(controllerType == NULL)
            返回base.GetControllerInstance(RequestContext的,controllerType);        VAR控制器= kernel.TryGet(controllerType)作为一个IController;        如果(控制== NULL)
            返回base.GetControllerInstance(RequestContext的,controllerType);        VAR standartController =控制器控制器;        如果(standartController是IIoCController)
            ((IIoCController)standartController).SetIoc(内核);        返回standartController;
    }    类NanocrmContainer:Ninject.Modules.NinjectModule
    {
        公共覆盖无效负载()
        {
            // ...            Bind<DomainModel.Entities.db>().ToSelf().InRequestScope().WithConstructorArgument(\"connection\", 数据源= LIMS;初始目录= nanocrm;坚持安全信息= TRUE;用户ID = ***;密码= ***);
        }
    }
}

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

 公共类UserRepository:IUserRepository
{
    私人分贝的DataContext;
    私人IUserGrou prepository userGrou prepository;    公共UserRepository(DB的DataContext,IUserGrou prepository userGrou prepository)
    {
        this.dataContext = DataContext的;
        this.userGrou prepository = userGrou prepository;
    }
}

那么的DataContext 实例被创建由Ninject(如果没有人在此请求范围内创建)。

那么麻烦,现在是 - ?在哪里调用的DataContext 方法 .Dispose()

UPD

所以我从后面的 KeeperOfTheSoul 的意见,并在这样的方式解决这个问题:

 公共覆盖无效ReleaseController(一个IController控制器)
    {
        base.ReleaseController(控制器);        变种DB = kernel.Get&LT; D​​omainModel.Entities.db&GT;();
        db.Dispose();
    }


解决方案

一个好地方来处理,这是在<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.releasecontroller%28v=VS.100%29.aspx\"相对=nofollow> IControllerFactory.ReleaseController ,如:

 公共覆盖无效ReleaseController(){
    base.ReleaseController();
    //做任何你需要在这里清理IoC容器
}

在NInject这可以通过使用的激活块,在请求开始ReleaseController期间创建可以激活块存储在HttpContext的当前项目控制器,当你可以检索previously创建激活块处理它

您还可以考虑使用 InScope 并具有自定义的范围,实施 INotifyWhenDisposed 。在这以后,使用相同与激活块,除了现在你存储在HttpContext的当前项目的范围。

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

解决方案

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.

这篇关于国际奥委会和处置的DataContext在asp.net MVC 2的应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆