Implementing the Repository and Finder patterns

Introduction

Over the last year I have been developing my own application using Domain Driven Design (DDD). I am also working on products in my day job that uses DDD. In the last month, myself and my fellow developers that I work with, went on a little journey to find the right way to implement the repository pattern including queries. My fellow devs and I wanted a solution to achieve the following goals:

  • A solid OO approach that was not bound to a specific technology. Meaning that we could develop this in C# or Java or what ever language.
  • No leaky abstraction. For example, we are using nHibernate at the moment, but in the future we might choose to use a different Object Relational Mapper (ORM). We don’t want our Repository or Finder interface to expose Nhibernate interfaces like “ISession” or “ICriteria”.
  • A repository per aggregate root.
  • No code duplication
  • Fully testable, driven out by our unit tests and me able to mock out the dependancies.
  • Friendly to our Inversion of Control (IoC) framework (ninject, spring.net and castle Windsor etc)
  • Provide a fluent interface to our repositories.

None of us are new to the Repository pattern or ways to implement query objects, so we all have ideas and existing code for tackling this. Combined we come up with this.

In my own application, my implementation used extension methods, its worked well, but because extension methods are static, i had no way of mocking them out  with Rhino mocks. This was not a showstopper, but meant that when i was writing unit tests in my service layer for example i have to set up the data to satisfy the logic in the extension methods.

Throughout the rest of this post, i will be using code from my own application.

The desired result


Here is an example of how we intent to use our repositories:


ApplicationUser user = applicationUserRepository
    .Find.ByLoginName(request.LoginName);

As you can see the repository has a find property on it that exposes a  ByLoginName method that takes a string argument and returns a single ApplicationUser object.

Entity Implementation


The ApplicationUser is a Entity, all of my Entities inherit from a base class called EntityBase:

public abstract class EntityBase
{
    private int id; 

    protected EntityBase() : this(0) { } 

    protected EntityBase(int id)
    {
        this.id = id;
    } 

    public int Id
    {
        get { return this.id; }
    } 

    public abstract bool IsValid();

    ...
}

Not much to it this, all my entities have an identity and i want all my entities to be able to state if the data they contain is valid

Repository Implementation

All of my repositories extend a base IRepository interface.

public interface IRepository<T> where T : EntityBase
{
    T Get(int id);
    void Save(T entity);
}

As you can see the generic type is constrained by the EntityBase type. The IRepository interface is not used directly outside of my repository layer, but is extended by the typed Repository interfaces:

public interface IApplicationUserRepository : IRepository<ApplicationUser>
{
    IApplicationUserFinder Find { get; }
}

In my application, I use dependency injection so my repositories are injected using the typed interface.  IApplicationUserRepository has one member being the Finder interface (more on that below).

One of my objectives was to remove duplicate code, in my effort to do this, i have an abstract class in which all my repositories inherit from.

public abstract class EntityRepository<T> : IRepository<T> where T : EntityBase
{
    protected readonly IPersistanceRepository repository;

    public EntityRepository(IPersistanceRepository repository)
    {
       this.repository = repository;
    }     

    public virtual T Get(int id)
    {
       return repository.Get<T>(id);
    } 

    public virtual void Save(T entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        } 

        if (entity.IsValid())
        {
             repository.Save(entity);
        }
    } 

     protected IQueryable<T> Query()
     {
         return repository.Query<T>();
     }

 }

This class must be supplied an instance of IPersistanceRepository.  Here is the IPersistanceRepository interface

public interface IPersistanceRepository
{
    T Get<T>(int id);
    void Save<T>(T entity);
    IQueryable<T> Query<T>();
}

A concrete implementation of the  IPersistanceRepository interface is the technology / ORM specific stuff. I am using NHibernate 2.0, so my concrete implementation is called “NHibernateRepository”. By using the IPersistanceRepository interface i am keeping the specifics abstracted away inside the concrete class. I have been able to successfully swap my IPersistanceRepository instance from NHibernate to a DB4o implementation with ease and no effect to my repositories.

Finder Implementation

Like the IRepository interface is used as a base interface, i also have a base IEntityFinder interface which again is not directly used outside of my repository layer.

public interface IEntityFinder<T> where T : EntityBase
{
    IQueryable<T> DataSource { set; }
}

As you can see, the interface has a DataSource property of IQueryable, the reason for this is that I am using System.Linq in my project which I will come onto later. But its purpose is to give the Finder a datasource. Now for the IApplicationUserFinder interface.

public interface IApplicationUserFinder : IEntityFinder<ApplicationUser>
{
    ApplicationUser ByLoginName(string loginName);

    ApplicationUser ByToken(Guid token);
}

The typed Repository

Now for my implementation of my typed Repository.

public class ApplicationUserRepository : EntityRepository<ApplicationUser>, IApplicationUserRepository
{
    private readonly IApplicationUserFinder finder; 

    public ApplicationUserRepository(IPersistanceRepository repository, IApplicationUserFinder finder)
        : base(repository)
    {
        this.finder = finder; 

        this.finder.DataSource = Query();
    } 

    public IApplicationUserFinder Find
    {
        get { return finder; }
    }
}

This repository derives from EntityRepository and implements IApplicationUserRepository. Its constucted with its dependencies being injected. The Finder instance has it datasource set to IQuerable<ApplicationUser>.

The typed finder

using System.Collections.Generic;
using System.Linq;

public class ApplicationUserFinder : IApplicationUserFinder
{
    private IQueryable<ApplicationUser> users; 

    public IQueryable<ApplicationUser> DataSource
    {
        set { users = value; }
    } 

    public ApplicationUser ByLoginName(string loginName)
    {
        if (string.IsNullOrEmpty(loginName))
        {
            throw new ArgumentNullException("loginName");
        } 

        return users.Where(u => u.LoginName == loginName).FirstOrDefault();
    } 

    public ApplicationUser ByToken(Guid token)
    {
        return users.Where(u => u.Token == token).FirstOrDefault();
    }
}

What do we have then

We have our entity, repository and Finder created. The repository and Finder have typed interfaces, which means i can wire these up in my IoC container. My IEntityFinder interface sort of went against my goal of no leaky abstraction as its using System.Linq, but i think i can live with myself. By having my finder implement an interface i could have different concrete implementations.

My finder is returning a single instance of ApplicationUser. I could have finder methods that return Iquerable that allows for method chaining etc. Plus i have not allowed for “And”, “Or” or “Not” as that is a different topic. But i have a base to work on.

nibernate repository

To be more code complete here is a snippet of my NHibernate repository that returns the initial query. I am using nhibernate 2.0 with nhibernate.linq.

    using System.Linq;
    using NHibernate;
    using NHibernate.Linq;

    public class NHibernateRepository  : IPersistanceRepository
    {
        private readonly ISessionLocator sessionLocator;

        public NHibernateRepository(ISessionLocator sessionLocator)
        {
            this.sessionLocator = sessionLocator;
        }

        public T Get<T>(int id)
        {
            ISession session = sessionLocator.ActiveSession();

            return session.Get(id);
        }

        public void Save<T>(T entity)
        {
             ...
        }

        public IQueryable<T> Query<T>()
        {
            var qry = from t in sessionLocator.ActiveSession().Linq()
                      select t;

            return qry.AsQueryable();
        }
    }

The beauty of this that the NHibernate specific code is in one place, my repositories and finders have no knowledge of nhibernate. In my finders, i am using linq for objects and lambda’s for my logic. Because i am using IQuerable, i can build up the query through my finders and the execution is deferred until i call a method like “ToList” or “First” etc. The queryProvider in nhibernate.linq builds the sql statement and hits the database once with the specific query.

Finally a big thank you to Neil Martin and Tim Escott for their involvement on this. Please read this post “Creating Fluent finders and repositories part 1 which continues from this post.

Advertisements

23 responses to “Implementing the Repository and Finder patterns

  1. Pingback: Repository : Finder Pattern « Convex Corners

  2. Hi Russel,

    Great post indeed as said before. Do you have the example available for download? I would love to have a closer look at your implementation.

    thanks,
    Tom

  3. Hi, Russell,

    Hello. I rather like your article but I’m having a small problem imagining implementing it in my scenario of using Linq to SQL and not NHibernate. If I understand your design correctly, I need merely create a SqlRepository class which implements IPersistanceRepository, correct? Your NHibernateRepository is a fine example but I’m not sure it translates into a Linq to SQL solution as the DataContext would not return an object of a type from my model but rather one from a class from the designer.cs created by Linq to SQL (sqlmetal). To have it create a model object using the DataContext as a source would require a separate persistance repository for each model object:

    public IQueryable Query() {
    return from u in this.context.Users
    select new User {
    ID = u.ID,
    Email = u.Email,

    };
    }

    which isn’t as elegant a solution as your single NHibertateRepository plus it doesn’t work with the above IPersistanceRepository definition since the type T is associated with the methods and not with the interface itself. Any suggestions?

    Thanks,
    Scott

  4. Scott, thanks for the comment. I understand your issue with Linq for SQL. firstly linq for SQL is not oriented around DDD or the repository pattern. But you can bend it to work in this way. I have come across some good blog posts on implementing linq for SQL with the repository pattern that i hope will give you some tips on what you need to do.

    What i would say is that using the designer in Linq for sql is going to generate your classes for you. The code it creates is… well.. horrid. The designer will only take you so far. I would separate your domain model from the persistence layer (persistent ignorant). The domain model should represent the business model and behaviours that you are writing software for. Not just a bunch of Data Transfer objects (DTOs) that linq for sql gives you.

    I did start working on a post showing how to accompish this will linq for SQL, but its ended up being a “things I hate about Linq for SQL” post.

    Anyway , a good blog post, if you have the time, read the series by
    Ian Cooper.

  5. Travis, many reasons for not bloating your repository with find methods. The first reason is that your repository interface will grow and your class will become large and god-like. Another more valid reason, is seperation of concern. I can encapulate all my logic for finding an “entity” into a “finder” for that entity.

    As you have read this post, you should understand the role of the “IpersistenceRepository”. When you create a concrete implemation of this interface, it will be using a technology like nhibernate, db4o, ado.net etc etc. Its the same for the finders, the concrete finders will be using a technology to perform the query logic (detachedCriteria, Linq for Objects, native queries in db4o etc etc). Your application should be ignorant to technologies otherwise your application is coupled to a technology that may give you some pain in the future when you want to upgrade or replace it. My point being that my ApplicationUserRepository only knows about the interface for the finder, not the technology that used to perform the finding. I used an Inversion of Control container to inject my dependancies at runtime. So if i want to upgrade or replace my ORM technology i could create new finder objects and switch them in my IoC configuration. This is something that i have had to do.

    Another and final reason that i am going to give now is: Fluent interfaces. if you put your find method in your repository, how are you going to do method chaining? you would have to return your repository as the return type for your find methods in order to find by another method. The repository will have methods like “Save”, this not going to give a nice fluent-interface. I have a post in draft at the moment this expands this post by implementing a fluent interface on the finders that covers sorting, mulitple find methods chained together and pagination.

    To conclude, putting specific find methods into your repository is a bad design choice.

    Hope this helps 😉

  6. Excellent articles! I have been reading through your series here and like others would sure love to get my hands on a sample. I think it would pull together alot of the things you’ve been discussing.

    thanks!
    Bill

  7. In the example above (and possibly forced into other persistence implementations due to the design), isn’t Query() returning all the records of the requested type? If, for example, I had a forum application with 50,000 post records, then if I understand this correctly (not saying I do), then wouldn’t each and every find require loading all 50,000 records from the database so I can parse through them with the Find* methods?

  8. A motivating discussion is worth comment. I think that you should write more about this subject, it might not be a taboo
    matter but usually folks don’t speak about these topics. To the next! Kind regards!!

  9. I’m really impressed with your writing skills as well as
    with the layout on your weblog. Is this a paid theme or
    did you modify it yourself? Anyway keep
    up the excellent quality writing, it is rare to see a great blog like this one these days.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s