So here is my current UnitOfWork implementation. This one makes use of the somewhat new current_session_context_class feature. I think this is quite simple compared to some of the others you will find.
public interface IUnitOfWork : IDisposable { IUnitOfWork Start(); void BeginTransaction(); void CommitTransaction(); void RollbackTransaction(); }
public class UnitOfWork : IUnitOfWork { #region Dependencies public ISessionFactory SessionFactory { get; set; } #endregion #region IUnitOfWork Members public virtual void BeginTransaction() { var session = SessionFactory.GetCurrentSession(); if ( !session.Transaction.IsActive ) { session.BeginTransaction(); } } public virtual void CommitTransaction() { var session = SessionFactory.GetCurrentSession(); if ( session.Transaction.IsActive ) { session.Transaction.Commit(); } } public void RollbackTransaction() { var session = SessionFactory.GetCurrentSession(); if ( session.Transaction.IsActive ) { session.Transaction.Rollback(); } } public IUnitOfWork Start() { if ( !CurrentSessionContext.HasBind(SessionFactory) ) { var session = SessionFactory.OpenSession(); session.FlushMode = FlushMode.Commit; CurrentSessionContext.Bind(session); } return this; } #endregion #region IDisposable Members public void Dispose() { var session = CurrentSessionContext.Unbind(SessionFactory); var transaction = session.Transaction; if ( transaction.IsActive ) { transaction.Dispose(); } session.Dispose(); } #endregion }
All that’s required is this in the hibernate config section:
(for web apps):
<property name="current_session_context_class">web</property>
(for pretty much anything else):
<property name="current_session_context_class">thread_static</property>
and just the barebones bootstrapping:
var sessionFactory = new Configuration().Configure().BuildSessionFactory();
Of course, to get this to work you need to register that sessionFactory instance into your IoC container, and register the UnitOfWork type with the container with a transient lifecycle.
From there you can either explicitly create and dispose IUnitOfWork instances for each operation, or set up a HttpModule to create one at the start of each request and dispose of it in the end_request event.