I was recently asked how I get the context of “this” in the UoW relating to the current page request.
Before I get into the guts, I would like to provide a little context. My application has 20+ databases scattered across 4 machines.
123
IRepository<Customer>customerRepository;// customer database on server 1IRepository<Package>packageRepository;// customer database on server 1IRepository<Contact>contactRepository;// contact database on server 2
So, I might ask for a Customer object and a Package object and I want to get the same ISession for both and if I ask for the same Customer twice, I want to get the one from the 1st level cache (I’m using NHibernate). If I ask for a Contact object, I will get a different ISession. All opened sessions are managed by my UoW. So, when the page request is complete, I call UoW.Commit and all sessions are committed.
The “magic” if you will, happens in the global.asax. I was nosing around in Rhino.Commons for inspiration and adapted a technique I saw there. This is how it looks:
My NHibernateRepository gets injected with the UoW for the current HttpRequest and when the request is complete, the global.asax commits the whole thing.
Now, this is all the context of an ASP.NET MVC Controller, but I have a similar issue for other (non-web) services. In that context I am using AOP and decorating a particular method with [UnitOfWork], which looks like:
In that context I use a PerThreadLifetimeManager for the NHibernateUnitOfWork, and code ends up looking like:
12345
[UnitOfWork]publicvoidProcess(Jobjob){...}
You know, there is really no reason why you couldn’t do the same thing in the MVC context. You could basically ditch the global.asax event hooha and just annotate the Controller task:
I’d like to try this out next time I get back into ASP.NET MVC, the global.asax event technique felt a little too magical and I don’t think Uncle Bob would approve.