I have been using Ninject in a ASP.NET MVC application with a database. I am using a repository pattern and have a unit of work object that encapsulates the NHibernate ISession. The following is how I am binding together all the elements:
public class RepositoryModule : NinjectModule
public override void Load()
/* For demo only...this should be in the web.config. */
const string connectionString = @"Server=localhost; Port=3306; Database=trucktracker; Uid=root; Pwd='your_own_password';";
NHibernateHelper helper = new NHibernateHelper(connectionString);
public class SessionProvider : Provider<ISession>
protected override ISession CreateInstance(IContext context)
UnitOfWork unitOfWork = (UnitOfWork)context.Kernel.Get<IUnitOfWork>();
I have the UnitOfWork instance (wrapper around the NHibernate Session and thus the database connection) bound "InRequestScope". (By the way, I know that recently there was a Ninject defect fixing an issue with 'InRequestScope'. I am using Ninject bits that have that defect fixed.)
Here is more info if you want:
A reader brought to my attention that MySQL was starting a lot of threads that are tied to the application when he followed this recipe. I took a look and found that (as expected) Ninject is deactivating UnitOfWork instances at the rate of garbage collection. Left to its own, the rate that Ninject deactivated UnitOrWork instances was not sufficient to keep up with data access. More and more MySQL threads are added. Eventually the server runs out of resources.
Just to be certain everything was working, I forced GC by adding a GC.Collect() call. When I added this, the UnitOfWork instances are collected at a rate where MySQL threads were not continually increasing. Since it appears that I need to take control of the clean up of the UnitOfWork (and db connections), I added the following bit of code to the ASP.NET session end event:
IUnitOfWork uow = Kernel.Get<IUnitOfWork>();
This code disposes the unit of work and closes the NHibernate session.
Here are my questions:
1. I thought one of the benefit of using an IOC container was to let it manage the lifetime of the objects. Since I am writing code to manage the end of life of the UnitOfWork, it feels a bit like I am violating some IOC rule. Is the above code recommended? Is there a better approach for managing the lifetime of valuable resources (such as db connections)?
2. I understand that Ninject is used outside of ASP.NET. I also read Nate's explanation how Ninject (circa March 2009) managed the life-cycle of objects (WeakReference and a timer). I was wondering if the 'InRequestScope' life-cycle management could be improved by tapping into the session end event? As per Nate's blog post, it is currently tied to the lifetime of the 'HttpContext.Current' object. Since you have the object, why not register for the end session event and release all the 'InReqestScope' objects?
Thanks for all your help and congrats on the recently release.