Using IoC and dataContext in asp.net mvc 2 application

I have 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 a class defined as:

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

then an instance of dataContext is created (if no one was created in this request area) using Ninject.

So now the problem: where to call the dataContext .Dispose() method?

UPD

so I followed the advice of KeeperOfTheSoul and solved the problem this way:

  public override void ReleaseController(IController controller) { base.ReleaseController(controller); var db = kernel.Get<DomainModel.Entities.db>(); db.Dispose(); } 
+2
source share
3 answers

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

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

In NInject, this can be processed using the area of the activation block , at the beginning of the request when creating the controller, you can save the activation block in the current HttpContext elements, during ReleaseController you can get the previously created activation block and destroy it.

You can also use InScope and have a special scope of INotifyWhenDisposed . After that, the use will be the same as with the activation block, except that now you save the area in the current HttpContext elements.

+3
source

The pattern that is sometimes used to remove db connections is to call Dispose from the finalizer.

 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 } } 
+2
source

You can connect it to Application_EndRequest.

+1
source

All Articles