Fixing Leaky Repository Abstractions with LINQ
One of the issues with current implementations of the Repository pattern is that ORM specific details can leak into the Repository interface. Most commonly this takes the form of concrete ORM querying machinery such as Query Objects, Expressions or custom object query languages. This weakening of the Repository abstraction is undesirable because it can make it more difficult to use our Repositories in different ways. For example using a fake repository to speed up our unit tests.
Enter LINQ. With language-level support for building expressions, we can now shore up our Repository interface in a completely abstract way. Our query expressions are simply handed off to the appropriate LINQ-provider which does the heavy-lifting for us. Even better, normal collections can be queried using LINQ and so implementing trivial in-memory fake repositories is dead easy. We used this approach on BackgroundMotion and it worked pretty well. Here’s what some of the code looks like:
// our Repository contract... public interface IRepository<T> where T : IIdentifiable { int Count(); int Count(Expression<Func<T, bool>> expression); void Add(T entity); void Remove(T entity); void Save(T entity); T FindOne(int id); T FindOne(Expression<Func<T, bool>> expression); bool TryFindOne(Expression<Func<T, bool>> expression, out T entity); IList<T> FindAll(); IList<T> FindAll(Expression<Func<T, bool>> expression); IQueryable<T> Find(); IQueryable<T> Find(int id); IQueryable<T> Find(Expression<Func<T, bool>> expression); } // and this is how we used our real Repository implementation Repository<Contribution> .Find(c => c.ApprovedById == null); // or... Repository<Tag> .Find() .OrderBy(t => t.Value) .Take(Constants.PageSize) .ToList();
Using this approach we were able to implement a fake Repository that used simple collections internally and just worked.
Good times. :-)
Trackbacks
Use this link to trackback from your own site.



Good stuff, makes me realize its time I got my head around LINQ though.
it seems, there are different implement of Repository. in this scenario, client must know about expression.
is this better way or I missed something ?
CustomerRepository customerRepository = new CustomerRepository();
customerRepository.GetCustomerByName(”name”);
Hi Nima,
You’re right, in this scenario, client code does know about the query expressions. One way to avoid this would be to create a layer of strongly-typed Repositorys that sit above this generic repository. However, if you do this you will lose the expressiveness of LINQ and so will have to create overloads/specifications that handle all your scenarios including sorting/paging etc.
Andrew.
Dear Andrew
Thanks so much
Dear Andrew,
Do you know if anyone documented the repository architecture or its use on a project outside of the background site? I am starting to use linq and I think the Core.dll code could speed up the development. But I don’t understand all the implications of its use, how to set it up on my code and I can’t seem to find anyone commenting on its use.
Thanks and best regards.
Hi Jesús,
People are using some of the code and patterns from BackgroundMotion but I’m not sure if anyone is using the Core assembly directly. The Repository pattern is from Domain Driven Design (Evans) and is also documented on MartinFowler.com. Jimmy Nilsson also has a book about using domain driven design patterns with .NET.
Cheers,
Andrew.