Repository Pattern – Part Four

If you like to take a look at previous posts, here they are:

There are few things I’d like to do to evolve the repositories.

  • Use Linq for specifications
  • Introduce Unit of Work (UoW)

Linq for specifications

I used specification objects to build specifications to create query criterion previously. I had to use specification objects to describe the criteria. This may be OK but when the number of criterion increases, management of these specification classes will be an overhead.

We can use Linq and Expressions in favor of our own explicit specifications. Given the popularity and acceptance of Linq, your data store will most likely support Linq in its API so your expressions in your criteria will play nicely.

I like to first separate the query and update portions of the repository. This allows us to be granular. Separating commands and queries from the repository gives me flexibility. I can inject query into controllers which does nothing but querying the data store and building a view model. I can send commands to a message bus and handler of that command can depend on the IUpdateModel contract to persist. The query side may even be in the cache. This is a way to enable CQS (Command Query Seperation) in your domain.

I made the repository non generic and added type parameters to its methods. This makes injecting repositories easier into dependent components.

There is a linq specifications project at google code if like to use a linq based specification for the previously discussed explicit specification solution in part 3.

Unit Of Work

There are lots of materials you can find on the subject. Here are some links to get started…

One think you should be aware is that most data access tools you use (NHibernate, Linq To Sql, Entity Framwork, etc…) already utilize the unit of work pattern. NHibernate uses ISession and the latter two uses DataContext. They are all “units of work” which tracks changes to entities within its scope.

In this example, I used entity framework for persistence. The domain repository will be using that. The unit of work implementation follows the domain below.

public interface IQueryModel
{
	TEntity Get<TEntity>(Func<TEntity, bool> where) where TEntity : class;
	IEnumerable<TEntity> GetMany<TEntity>(Func<TEntity, bool> where) where TEntity : class;
	IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class;
}

public interface IUpdateModel
{
	void Save<TEntity>(TEntity dto) where TEntity : class;
	void Update<TEntity>(TEntity entity) where TEntity : class;
	void Delete<TEntity>(Func<TEntity, bool> predicate) where TEntity : class;
	void Delete<TEntity>(TEntity entity) where TEntity : class;
}

public interface IRepository : IQueryModel, IUpdateModel
{
}

public interface IPersistData
{
	void Persist();
	IPersistData New();
}

// Entity framework dependent data persister
public class EfDataContext : DbContext, IPersistData
{
	public DbSet<User> Users { get; set; }

	public EfDataContext()
		: base("RepositorySeries")
	{
	}

	#region Implementation of IPersistData

	public void Persist()
	{
		SaveChanges();
	}

	public IPersistData New()
	{
		return new EfDataContext();
	}

	#endregion
}

// simple entity
public class User
{
	[Key]
	public int UserID { get; set; }
	public string FullName { get; set; }
}

// Entity framework dependent repository
public class DomainRepository : IRepository
{
	private DbContext m_db;

	public DomainRepository(DbContext db)
	{
		m_db = db;
	}
	public DomainRepository()
	{
		m_db = new EfDataContext();
	}

	#region Implementation of IQueryModel

	public TEntity Get<TEntity>(Func<TEntity, bool> where) where TEntity : class
	{
		return m_db.Set<TEntity>().FirstOrDefault(where);
	}

	public IEnumerable<TEntity> GetMany<TEntity>(Func<TEntity, bool> where) where TEntity : class
	{
		return m_db.Set<TEntity>().Where(where);
	}

	public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
	{
		return m_db.Set<TEntity>();
	}

	#endregion

	#region Implementation of IUpdateModel

	public void Save<TEntity>(TEntity dto) where TEntity : class
	{
		m_db.Set<TEntity>().Add(dto);
	}

	public void Update<TEntity>(TEntity entity) where TEntity : class
	{
		m_db.Entry(entity).State = EntityState.Modified;
	}

	public void Delete<TEntity>(Func<TEntity, bool> predicate) where TEntity : class
	{
		var entity = m_db.Set<TEntity>().FirstOrDefault(predicate);

		m_db.Set<TEntity>().Remove(entity);
	}

	public void Delete<TEntity>(TEntity entity) where TEntity : class
	{
		m_db.Set<TEntity>().Remove(entity);
	}

	#endregion

	#region Implementation of IRepository

	public void Commit()
	{
		m_db.SaveChanges();
	}

	public void Rollback()
	{
		m_db = new EfDataContext();
	}

	#endregion
}

public interface IUnitOfWork
{
	IRepository Repository { get; }
	void Commit();
	void Rollback();
}

public class UnitOfWork : IUnitOfWork
{
	private IPersistData m_db;

	public UnitOfWork(IRepository repository, IPersistData db)
	{
		m_db = db;
		Repository = repository;
	}

	#region Implementation of IUnitOfWork

	public IRepository Repository { get; private set; }

	public void Commit()
	{
		try
		{
			m_db.Persist();
		}
		catch (Exception ex)
		{
			Rollback();

			throw ex;
		}
	}

	public void Rollback()
	{
		m_db = m_db.New();
	}

	#endregion
}

// sample app using all above
class Program
{
	static void Main(string[] args)
	{
		// get these from container (DI)
		IRepository repository = new DomainRepository();
		IPersistData db = new EfDataContext();

		// unit of work object
		var uow = new UnitOfWork(repository, db);

		// sample entity
		var u1 = new User { FullName = "Homer Simpson", };

		// add, edit, delete entities on the repository
		uow.Repository.Save(u1);

		// commit changes in unit of work
		uow.Commit();
	}
}

The interfaces and unit of work implementation does not have any dependency to a data access technology. DomainRepository and EfDataContext have dependencies to Entity Framework in this case. This implementation can be changed to some other data access technology easily.

Repository Pattern – Part Three

In my previous posts; part one and part two, I introduced my take on several versions of a repository implementation. I ended up a generic repository with an IQueryable getter and insert, update and delete methods. This is good enough in most scenarios.

But I will break this into two repositories and refer you to Greg Young’s article on repositories. His implementation brings a few benefits…

  • Explicit contract
  • Flexible implementation of generic internal repository (LINQ, ADO, hql, etc…)

Take 5

I will define the generic repository contract and the explicit customer repository as below:

    public interface IRepository<T>
    {
        IList<T> FindAllBy(ISpecification<T> specification);
        void Insert(T item);
        void Delete(T item);
        void Update(T item);
    }

    public interface ICustomerRepository
    {
        Customer GetCustomerByID(string customerID);
        IList<Order> GetOrdersByCustomerID(string customerID);
        IList<Customer> GetAllCustomers();
        void Insert(Customer customer);
        void Delete(Customer customer);
        void Update(Customer customer);
    }

If you have noticed, the customer repository is the explicit contact which I have started with (See Part 1 of the series). For the keen eye, the original generic repository contract has a specification (criteria) a parameter to filter the requested entities.

Let’s define some specifications. They will be needed to filter customers by name (for the generic inner repository).

    public class AllCustomersSpecification : ISpecification<Customer>
    {
        #region Implementation of ISpecification<in Customer,out Customer>

        public IQueryable<Customer> SatisfyingElementsFrom(IQueryable<Customer> candidates)
        {
            return candidates;
        }

        #endregion
    }

    public class CustomerNameSpecification : ISpecification<Customer>
    {
        private readonly string m_name;

        public CustomerNameSpecification(string name)
        {
            m_name = name;
        }

        #region Implementation of ISpecification<in Customer,out Customer>

        public IQueryable<Customer> SatisfyingElementsFrom(IQueryable<Customer> candidates)
        {
            return candidates.Where(c => c.ContactName == m_name);
        }

        #endregion
    }

Now the implementations of the generic repository and the explicit customer repository. Customer repository is a composition.

    public class Repository<T> : IRepository<T>
    {
        // TODO: to be implemented w/ LINQ, EF, NHibernate, etc...

        #region Implementation of IRepository<T>

        public IList<T> FindAllBy(ISpecification<T> specification)
        {
            throw new NotImplementedException();
        }

        public void Insert(T item)
        {
            throw new NotImplementedException();
        }

        public void Delete(T item)
        {
            throw new NotImplementedException();
        }

        public void Update(T item)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class CustomerRepository : ICustomerRepository
    {
        private readonly IRepository<Customer> m_innerRepo;

        public CustomerRepository()
        {
            m_innerRepo = new Repository<Customer>();
        }
        public CustomerRepository(IRepository<Customer> repository)
        {
            m_innerRepo = repository;
        }

        #region Implementation of ICustomerRepository

        public Customer GetCustomerByID(string customerID)
        {
            return m_innerRepo.FindAllBy(new CustomerIDSpecification(customerID)).First();
        }

        public IList<Order> GetOrdersByCustomerID(string customerID)
        {
            return GetCustomerByID(customerID).Orders;
        }

        public IList<Customer> GetAllCustomers()
        {
            return m_innerRepo.FindAllBy(new AllCustomersSpecification());
        }

        public void Insert(Customer customer)
        {
            m_innerRepo.Insert(customer);
        }

        public void Delete(Customer customer)
        {
            m_innerRepo.Delete(customer);
        }

        public void Update(Customer customer)
        {
            m_innerRepo.Update(customer);
        }

        #endregion
    }

Nice thing about CustomerRepository is that it is a composition of the the generic repository. This means that a change in the implementation of generic repository does not affect the CustomerRepository since this is not inheritance anymore.

I am pretty happy with this so far.

Repository Pattern – Part Two

In my previous post, I introduced my take on several versions of a repository implementation.

Take 1

We start with a simple, explicit customer repository.

    public interface ICustomerRepository
    {
        Customer GetCustomerByID(string customerID);
        IList<Order> GetOrdersByCustomerID(string customerID);
        IList<Customer> GetAllCustomers();
        void Insert(Customer customer);
        void Delete(Customer customer);
        void Update(Customer customer);
    }

While being explicit, I am putting bunch of methods like “GetCustomerByID” and “GetOrdersByCustomerID”. But what if I want to find customers and orders by different methods such as “GetCustomersByCategory”, “GetCustomerByLocation”, and so on…

    public interface ICustomerRepository
    {
        // Query Methods
        Customer GetCustomerByID(string customerID);
        Customer GetCustomerByCompanyName(string city);
        Customer GetCustomerByCity(string city);
        Customer GetCustomerByPostalCode(string city);
        IList<Order> GetOrdersByCustomerID(string customerID);
        IList<Customer> GetAllCustomers();

        // Command Methods
        void Insert(Customer customer);
        void Delete(Customer customer);
        void Update(Customer customer);
    }

I can easily end up having many more get methods about orders, details and so on. It won’t be ideal.

Take 2

I can break that big explicit interface into smaller contracts and implement them where necessary. I prefixed the interfaces with query and command to separate the two. Naming is demonstration purposes only, I wouldn’t name them. It is only to make a point…

    public interface ICustomerRepositoryQuery
    {
        Customer GetCustomerByID(string customerID);
        Customer GetCustomerByCompanyName(string city);
        Customer GetCustomerByCity(string city);
        Customer GetCustomerByPostalCode(string city);
        IList<Order> GetOrdersByCustomerID(string customerID);
        IList<Customer> GetAllCustomers();
    }

    public interface ICustomerRepositoryCommand
    {
        void Insert(Customer customer);
        void Delete(Customer customer);
        void Update(Customer customer);
    }

    public interface ICustomerRepository
        : ICustomerRepositoryQuery, ICustomerRepositoryCommand
    {
        void Save(Customer customer);
    }

Looks like a little bit better but it is still lipstick on pig.

Take 3

I can collapse all the explicit get methods down to one queryable entity collection. The consumer of this repository, most likely a service, can use Linq to Objects to do queries. That will remove the need for multiple get methods.

    public interface ICustomerRepository
    {
        IQueryable<Customer> GetCustomers();
        void Insert(Customer customer);
        void Delete(Customer customer);
        void Update(Customer customer);
    }

Looks like an improvement but what did I gain or lose?

Gains

  • Simplified repository
  • Power of Linq to query in a uniform programming model
  • Deferred execution (Linq feature)

Losses (might be a tad bit strong but you get the point)

  • We will break the Law Of Demeter by not being explicit. Instead of repository.GetCustomerByID("ALFKI") I need to do repository.Customers().Where(c => c.CustomerID.Equals("ALFKI").SingleOrDefault().
  • Testing this will be a little bit harder. We can mock or create our own DataContext in the fake repository to test. I could also simply use .AsQueryable() and return IQueryable so that is not a big deal.

Take 4

I want to address a few things in the latest repository. First, since I made it simpler by using IQuery, I can make the repository generic.

    public interface IRepository<T>
    {
        IQueryable<T> GetItems();
        void Insert(T item);
        void Delete(T item);
        void Update(T item);
    }

Second, I could replace IList<T> GetItems() with IList<T> GetItems(). That would be a start halfway with the “Law of Delimiter” boo boo I did. It wouldn’t achieve a whole lot though. I would use the deferred execution of getting items. For example, if I returned IList<T> instead of IQueryable<T>, this call below would get all the customers from the database into memory first and then filter them.

Notice the generated SQL? There is no where clause to filter data which is not good. The filtering would be in memory after all the record were returned with IList. Imagine you have a million customers and you would get all of them from database into memory to get one customer with id “ALFKI”.

Here is the SQL if we used IQueriable instead:

Now we have the proper SQL so we’ll stick to IQueryable. I didn’t address the law of delimiter though. May be I could achieve that in the service by exposing more explicit behavior. By the way, the assumption is that this service is not public API, it is only used by the components within one system.

If this service was to be public then I would have to limit the number of customers returned over the wire somehow. I can’t let anyone get one million customers anytime. I could enforce authorization on the call.

For example; some users in particular roles would be able call service.GetCustomers(1000000000); and others would only get 100 customers max at a time by service.GetCustomers(100). I could also cache the customers into memory within the service.

    public interface ICustomerService
    {
        IList<Customer> GetCustomers(int count);
    }

This deserves another discussion entirely but the point is, there is no silver bullet, remember? Every solution makes sense in its context and we are not looking for “one solution” to rule them all…

Stay tuned…

Repository Pattern – Part One

When I build repositories in my domain, I often find my find myself in a dilemma. Should I create generic, boilerplate code for reuse, or should I be explicit? How should I design my repositories in a way that it is as technology agnostic as possible? I don’t want to care about DAL while I am designing my repositories.

There is no “One” design; every project is different. It is silly to even dream up one… I will create series of posts which will be an exercise to compare and discuss each implementation.

Objective

Build a service layer and repository implementations to service Customer entities in a console application. The application uses DDD (Domain Driven Design) in its architecture.

Solution

I will use different ORMs and patterns to implement the repository pattern. I will do this iteratively and improve implementation as I go. I’ll try to use various ORMs (Linq to Sql, EF, NHibernate),  persistence stores (MongoDB, SQL Server), design patterns and techniques (Specification, Services, IoC) along the way.

Let’s see where we’ll end up…

Resources