3
\$\begingroup\$

I have the following code implemented in C# for NHibernate:

public class UnitOfWork : IDisposable {
        private ISession _session;
        private ITransaction _transaction;

        public UnitOfWork() {  
            _session = NHibernateHelper.OpenSession();
            _transaction = _session.BeginTransaction();
        }

        public IProductRepository Products {
            get {
                return new ProductRepository(_session);
            }
        }

        public IPersonRepository People {
            get {
                return new PersonRepository(_session);
            }
        }

        public void SaveChanges() {

            if (_transaction == null) {
                throw new InvalidOperationException("Unit Of Work already saved");
            }

            _transaction.Commit();
        }

        public void Dispose() {
            //throw new NotImplementedException();
            CloseSession();
            CloseTransaction();
        }

        #region Transaction and Session Management Methods

        public void BeginTransaction() {
            _transaction = _session.BeginTransaction();
        }

        public void CommitTransaction() {
            // _transaction will be replaced with a new transaction            // by NHibernate, but we will close to keep a consistent state.
            _transaction.Commit();

            CloseTransaction();
        }

        public void RollbackTransaction() {
            // _session must be closed and disposed after a transaction            // rollback to keep a consistent state.
            _transaction.Rollback();

            CloseTransaction();
            CloseSession();
        }

        private void CloseTransaction() {
            _transaction.Dispose();
            _transaction = null;
        }

        private void CloseSession() {
            _session.Close();
            _session.Dispose();
            _session = null;
        }

        #endregion
    }

As I have doubts whether this implementation is right or not, I felt the need for other people to correct my work and suggest for further improvements. I feel like somehow the Repository should not reside inside Unit of Work.

Then again, I need the Unit of Work pattern to inject the same session in all repositories as it also felt I'm not utilizing its use if I use 1 session inside each repository methods.

This is how I consume my Unit of Work inside service layer:

public class PersonService {

        private UnitOfWork uow = new UnitOfWork();

        public IEnumerable<Person> GetAllPerson() {
            var uo = new UnitOfWork();

            return uo.People.GetAll();
        }

        /// <summary>
        /// 1st implementation of scoping unit of work session lifetime
        /// </summary>
        /// <returns></returns>
        public void AddPerson() {
            var uo = new UnitOfWork();

            uo.People.Add(new Person() {
                Fname = "Sonny",
                Mname = "Ramirez",
                Lname = "Recio"
            });
            uo.SaveChanges();

        }

        /// <summary>
        /// 2nd implementation of scoping unit of work session lifetime
        /// </summary>
        /// <returns></returns>
        public PersonInfoViewModel GetInfo() {
            using (UnitOfWork uo = new UnitOfWork()) {
                //todo: implementation
            }

            return uow.People.GetInfo();
        }


    }

Feel free to correct my code as you see fit. I think I already saw a different implementation of UoW which it doesn't have any repository residing in it, but I don't like how it was implemented.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.