Unit of work and Repository Pattern with nHibernate and linq

The code for this post can be found here

I just implemented Unit of Work and Repository Pattern on one of my very exciting new project. The project itself architected using Onion architecture and domain model strictly followed Domain Driven Design principles. The implementation of repository pattern provided me flexibility and abstraction to achieve persistence ignorance. After much deliberation and discussion I selected nHibernate and linq as an implementation technology however, the project architecture made it possible to replace this implementation with another technology i.e. Entity Framework.

So, let’s not waste any time and jump into code.

namespace RepositoryPattern.Infrastructure
{
	public interface IEntityKey<TKey>
	{
		TKey Id { get; }
	}
}

IEntityKey interface is part of core infrastructure project and provides generic identity to domain model objects.

namespace RepositoryPattern.Infrastructure
{
	public interface IReadOnlyRepository<TKey, TEntity> where TEntity : class, IEntityKey<TKey>
	{
		IQueryable<TEntity> All();
		TEntity FindBy(Expression<Func<TEntity, bool>> expression);
		IQueryable<TEntity> FilterBy(Expression<Func<TEntity, bool>> expression);
		TEntity FindBy(TKey id);
	}
}

IReadOnlyRepository provides data fetch services and exposes IQueryable interface. As you may already know that  the use of IQueryable interface is controversial. A few well respected people in .NET neighbourhood expressed their data access concerns but I simply love IQueryable. I recommend you investigate these concerns and make your own decision. In my case, this interface only exposed to well defined. controlled and secure service where all these concern are dealt with. FindBy and FilterBy methods accepts Expression. The expression provides flexibility and compatibility with linq but also boosts performance by delaying the execution to achieve optimised queries to database.

namespace RepositoryPattern.Infrastructure
{
	public interface IPersistRepository<TEntity> where TEntity : class
	{
		bool Add(TEntity entity);
		bool Add(IEnumerable<TEntity> items);
		bool Update(TEntity entity);
		bool Delete(TEntity entity);
		bool Delete(IEnumerable<TEntity> entities);
	}
}

IPersistRepository is responsible for writing data to repository. I have separated read and write interfaces as our services may only require read only facility or vice versa.

namespace RepositoryPattern.Infrastructure
{
	public interface IUnitOfWork : IDisposable
	{
		void Commit();
		void Rollback();
	}
}

IUnitOfWork interface implements unit of work pattern, encapsulates the transaction functionalities by exposing commit and rollback operations.

Now we have set-up our infrastructure abstraction, let’s implement infrastructure layer using nHibernate in a separate project called RepositoryPattern.Data.Orm.nHibernate. As I mentioned above, if we like to implement the infrastructure layer using Entity Framework; we could add another project called RepositoryPattern.Data.Orm.EntityFramework. Lets worry about nHibernate implementation using linq for now.

namespace RepositoryPattern.Data.Orm.nHibernate
{
	public class Repository<TKey, T> : IPersistRepository<T>,
		IReadOnlyRepository<TKey, T> where T : class, IEntityKey<TKey>
	{
		private readonly ISession _session;
		public Repository(ISession session)
		{
			_session = session;
		}

		public bool Add(T entity)
		{
			_session.Save(entity);
			return true;
		}

		public bool Add(System.Collections.Generic.IEnumerable<T> items)
		{
			foreach (T item in items)
			{
				_session.Save(item);
			}
			return true;
		}

		public bool Update(T entity)
		{
			_session.Update(entity);
			return true;
		}

		public bool Delete(T entity)
		{
			_session.Delete(entity);
			return true;
		}

		public bool Delete(System.Collections.Generic.IEnumerable<T> entities)
		{
			foreach (T entity in entities)
			{
				_session.Delete(entity);
			}
			return true;
		}

		public IQueryable<T> All()
		{
			return _session.Query<T>();
		}

		public T FindBy(System.Linq.Expressions.Expression<Func<T, bool>> expression)
		{
			return FilterBy(expression).SingleOrDefault();
		}

		public IQueryable<T> FilterBy(System.Linq.Expressions.Expression<Func<T, bool>> expression)
		{
			return All().Where(expression).AsQueryable();
		}

		public T FindBy(TKey id)
		{
			return _session.Get<T>(id);
		}
	}
}

Repository class implements IPersistRepository and IReadOnlyRepository interfaces. This generic implementation provides CRUD operations to all entities and keeps code DRY. The generic functionality could be extended to add entity specific logic by using Decorator Pattern.

The most important part of the implementation is a constructor of Repository class. The instance of ISession is injected via constructor injection. The injection of session instance provides flexibility to control lifetime of object via unit of work or IOC container  i.e. Castle Windsor. The session make full use of linq features supported in nHibernate 3 as shown below.

return _session.Query<T>();

Now we have repository pattern implemented, lets proceed to implement unit of work pattern.

namespace RepositoryPattern.Data.Orm.nHibernate
{
	public class UnitOfWork : IUnitOfWork
	{
		private readonly ISessionFactory _sessionFactory;
		private readonly ITransaction _transaction;
		public ISession Session { get; private set; }

		public UnitOfWork(ISessionFactory sessionFactory)
		{
			_sessionFactory = sessionFactory;
			Session = _sessionFactory.OpenSession();
			Session.FlushMode = FlushMode.Auto;
			_transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
		}

		public void Commit()
		{
			if (!_transaction.IsActive)
			{
				throw new InvalidOperationException("Oops! We don't have an active transaction");
			}
			_transaction.Commit();
		}

		public void Rollback()
		{
			if (_transaction.IsActive)
			{
				_transaction.Rollback();
			}
		}

		public void Dispose()
		{
			if (Session.IsOpen)
			{
				Session.Close();
			}
		}
	}
}

The implementation of IUnitOfWork is very simple and clean, again the most important part of the code is constructor. Instance of ISessionFactory is injected via constructor injection. The life time of ISessionFactory is controlled by IOC container.

The implementation of unit of work and repository pattern provides flexibility, extensibility and kept code clean and most importantly DRY.

The code for this post can be found here

About these ads

, , , ,

  1. #1 by Ciprian on June 10, 2011 - 13:21

    Excellent article! I am using a unit of work implementation with Entity Framework but didn’t know how to use it with NHibernate, this is just what I needed. Thank you!

  2. #2 by codejammr on January 18, 2012 - 03:18

    I would love to see your Windsor Component Registrations for this code/

  3. #3 by Vincent on April 19, 2012 - 12:37

    how do you implement IOC?

  4. #4 by Vincent on April 19, 2012 - 13:36

    Hi it’s me again, I am newbie to IOC, I found your example is quite useful, but when I am trying to integrate with Structuremap, the ISession is different to each repository, so I can’t maintain the uow at all, can you please give some sample to point me out? Thanks

  5. #5 by nazakat ali on April 19, 2012 - 13:57

  1. NHibernate Guide « Notes to Remember
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: