Is this a right way to use NHibernate?
Posted
by Venemo
on Stack Overflow
See other posts from Stack Overflow
or by Venemo
Published on 2010-04-26T22:28:55Z
Indexed on
2010/04/26
22:33 UTC
Read the original article
Hit count: 321
I spent the rest of the evening reading StackOverflow questions and also some blog entries and links about the subject. All of them turned out to be very helpful, but I still feel that they don't really answer my question.
So, I'm developing a simple web application. I'd like to create a reusable data access layer which I can later reuse in other solutions. 99% of these will be web applications. This seems to be a good excuse for me to learn NHibernate and some of the patterns around it.
My goals are the following:
- I don't want the business logic layer to know ANYTHING about the inner workings of the database, nor NHibernate itself.
- I want the business logic layer to have the least possible number of assumptions about the data access layer.
- I want the data access layer as simplistic and easy-to-use as possible. This is going to be a simple project, so I don't want to overcomplicate anything.
- I want the data access layer to be as non-intrusive as possible.
Will all this in mind, I decided to use the popular repository pattern. I read about this subject on this site and on various dev blogs, and I heard some stuff about the unit of work pattern.
I also looked around and checked out various implementations. (Including FubuMVC contrib, and SharpArchitecture, and stuff on some blogs.) I found out that most of these operate with the same principle: They create a "unit of work" which is instantiated when a repository is instantiated, they start a transaction, do stuff, and commit, and then start all over again. So, only one ISession
per Repository
and that's it. Then the client code needs to instantiate a repository, do stuff with it, and then dispose.
This usage pattern doesn't meet my need of being as simplistic as possible, so I began thinking about something else.
I found out that NHibernate already has something which makes custom "unit of work" implementations unnecessary, and that is the CurrentSessionContext
class. If I configure the session context correctly, and do the clean up when necessary, I'm good to go.
So, I came up with this:
I have a static class called NHibernateHelper
. Firstly, it has a static property called CurrentSessionFactory
, which upon first call, instantiates a session factory and stores it in a static field. (One ISessionFactory
per one AppDomain
is good enough.) Then, more importantly, it has a CurrentSession
static property, which checks if there is an ISession
bound to the current session context, and if not, creates one, and binds it, and it returns with the ISession
bound to the current session context.
Because it will be used mostly with WebSessionContext
(so, one ISession
per HttpRequest
, although for the unit tests, I configured ThreadStaticSessionContext
), it should work seamlessly. And after creating and binding an ISession
, it hooks an event handler to the HttpContext.Current.ApplicationInstance.EndRequest
event, which takes care of cleaning up the ISession
after the request ends. (Of course, it only does this if it is really running in a web environment.)
So, with all this set up, the NHibernateHelper
will always be able to return a valid ISession
, so there is no need to instantiate a Repository instance for the "unit of work" to operate properly. Instead, the Repository
is a static class which operates with the ISession
from the NHibernateHelper.CurrentSession
property, and exposes some functionality through that.
I'm curious, what do you think about this? Is it a valid way of thinking, or am I completely off track here?
© Stack Overflow or respective owner