My goal was to use the NHibernate Session and to create a UnitOfWork class that I could use thoughout my project. My goals are:Calling Commit should commit everything including un-flushed state (was mostly out of the box I believe)Rollback should roll back everything including whatever was not flushed from the scope yetDisposing the UnitOfWork without a Commit or a Rollback should not persist any changes to the database.I wanted to wrap flush so everyone in my team understood what it was doing.And also expose various functions of the NHibernate session that I want to use in my project.My project requires:This to work with WebApi where I use an ActionFilterAttribute to begin commit the unit of work.This to work with Mvc where I use an ActionFilterAttribute to begin commit the unit of work.In a console application that is used for background processes. In this use-case, I need to be able to begin and end multiple transactions during a single execution of the jobs that it runs.Some additional information:I'm using Autofac, so the ISession being injected is just a Vanilla NHibernate Session.I would love some constructive criticism on the approach.public class UnitOfWorkSession : IUnitOfWorkSession{    private ISessionFactory _sessionFactory;    private readonly IEnumerable<IChangeTracker<Member>> _memberChangeTrackers;    private readonly IEnumerable<IChangeTracker<ForumThread>> _forumThreadChangeTrackers;    private readonly IEnumerable<IChangeTracker<Comment>> _commentTrackers;    private ISession _session { get; set; }    private bool _committed { get; set; }    private bool _rollback { get; set; }    private bool _isActive = false;    public UnitOfWorkSession(ISessionFactory sessionFactory, IEnumerable<IChangeTracker<Member>> memberChangeTrackers, IEnumerable<IChangeTracker<ForumThread>> forumThreadChangeTrackers, IEnumerable<IChangeTracker<Comment>> commentTrackers)    {        _sessionFactory = sessionFactory;        _memberChangeTrackers = memberChangeTrackers;        _forumThreadChangeTrackers = forumThreadChangeTrackers;        _commentTrackers = commentTrackers;    }    private ISession Session    {        get { return _session; }    }    public ITransaction BeginNewUnitOfWork()    {        if (_isActive)            throw new InvalidOperationException(There is already an active Unit of work);        // Every unit of work will use a fresh NHibernate session. Committing or Rollback will dispose this session.        _session = _sessionFactory.OpenSession(new AuditInterceptor(_memberChangeTrackers, _forumThreadChangeTrackers, _commentTrackers));        var newTransaction = _session.BeginTransaction();        _isActive = true;        _committed = false;        _rollback = false;        return newTransaction;    }    public void Commit()    {        if (_session.Transaction.IsActive)        {            try            {                _session.Transaction.Commit();            }            catch            {                _session.Transaction.Rollback();                throw;            }            finally            {                _committed = true;                _isActive = false;                _session.Dispose();            }        }    }    /* Used to manually rollback a transaction/prevent a commit */    public void RollBack()    {        try        {            _session.Clear();            _session.Transaction.Rollback();        }        finally        {            _isActive = false;            _rollback = true;            _session.Dispose();        }    }    public void Save(object entity)    {        _session.Save(entity);    }    public void Update(object entity)    {        _session.Update(entity);    }    public void SaveOrUpdate(object entity)    {        _session.SaveOrUpdate(entity);    }    public void Delete(string sqlStatement)    {        _session.Delete(sqlStatement);    }    public void Delete(object entity)    {        _session.Delete(entity);    }    public void Delete(string sqlStatement, Guid id)    {        if (sqlStatement != null && sqlStatement.IndexOf(?) == -1)            throw new InvalidParameterValueException(sqlStatement,Must have a ? mark in the sql statement to inject the id);        _session.Delete(sqlStatement, id, NHibernateUtil.Guid);    }    public T Get<T>(object id, LockMode lockMode = null)    {        if (lockMode != null)            return _session.Get<T>(id, lockMode);        return _session.Get<T>(id);    }    public ISQLQuery CreateSQLQuery(string queryString)    {        return _session.CreateSQLQuery(queryString);    }    public IQueryable<T> Query<T>()    {        return _session.Query<T>();    }    // Note:    All this does is take the changes from nhibernate session and put it on the current un-committed transaction of that session.     //          This should be used very sparingly in cases where a conflict can occur in the Session.    //          Example of use: See SaveQuizResultCommand, where it is used to prevent a unique key violation occurring.    public void FlushToActiveTransaction(bool clearSession = false)    {        _session.Flush();        if (clearSession)            _session.Clear();    }    public void Clear()    {        _session.Clear();    }    public IStatistics Statistics    {        get { return _session.SessionFactory.Statistics; }    }    public void Dispose()    {        if (Session != null && Session.IsOpen && !_committed && !_rollback && Session.Transaction.IsActive)            Session.Transaction.Rollback();    }    public bool IsDirty()    {        return _session.IsDirty();    }    public bool IsOpen()    {        return _session.IsOpen;    }}
Unit of work using session for NHibernate for WebApi and MVC
c#;asp.net