I’ve been working quite alot on database-intensive applications lately and have been setting up a simple repository pattern with structuremap that I thought might be of interest.

First things first, I love structuremap, it’s an excellent IoC framework and it makes life so much easier when used to its full potential. Not just for dependency injection but for making applications truly loosely coupled. One oftenly overlooked feature is Structuremaps ability to decorate an inner class with a wrapper. Have a look at this for example:

For<IMovieRepository>().Use<MovieRepository>();
For<IMovieRepository>().DecorateAllWith<CachingMovieRepository>();

What we're doing here is simply injecting a concrete implementation for IMovieRepository called MovieRepository and then decorating or wrapping it with another concrete implementation called CachingMovieRepository. We could continue this chain with another wrapper, and another and another. Perhaps something like this:

For<IMovieRepository>().Use<MovieRepository>();
For<IMovieRepository>().DecorateAllWith<CachingMovieRepository>();
For<IMovieRepository>().DecorateAllWith<AuditingMovieRepository>();
For<IMovieRepository>().DecorateAllWith<LoggingMovieRepository>();

The outermost wrapper would now be a LoggingMovieRepository, which in turn would call an AuditingMovieRepository, which in turn would call a CachingMovieRepository that finally would call the MovieRepository and return some movies (hopefully).

This might sound weird and not make much sense if you’re not into IoC or the decorator pattern, but let me continue the example by showing the IMovieRepository interface (simplified of course) and just some possible implementations of the different implementors.

public interface IMovieRepository {
    Movie GetById(int id);
}

The interface, simplified to one method.

public class MovieRepository : IMovieRepository {
    Movie GetById(int id) {
        //Some db-call to fetch a movie and return it
        //For example:
        return dbContext.Movies.FindById(id);
    }
}

The only concrete implementation that actually does the heavy lifting of getting a movie from the database. Nothing really to see here.

public class CachingMovieRepository : IMovieRepository {

    private readonly IMovieRepository _repo;
    private readonly ICacheManager _cache;

    public CachingMovieRepository(IMovieRepository repo, ICacheManager cacheManager) {
        _repo = repo;
        _cache = cacheManager;
    }

    Movie GetById(int id) {
        //We try to get the movie from the cache
        var movie = _cache.TryGetMovie(id);
        
        if(movie == null)
        {
            return _repo.GetById(id);
        }
        return movie;
    }
}

Now it's getting interesting, the caching repo implements the interface and takes a parameter for another IMovieRepository to call in case it does not find the requested movie in the cache. It also needs an ICacheManager to do the actual cache look up.

public class AuditingMovieRepository : IMovieRepository {

    private readonly IMovieRepository _repo;
    private readonly IAuditManager _audit;

    public AuditingMovieRepository (IMovieRepository repo, IAuditManager audit){
        _repo = repo;
        _audit = audit;
    }

    Movie GetById(int id) {
        //We audit the call
        _audit.AuditGetMovie(int id);
        
        return _repo.GetById(id);
    }
}

And we can see the pattern forming, every IMovieRepository takes another IMovieRepository to call after it has completed its operations. In this case just auditing the call to the database and perhaps save who accessed which table for which entity.

public class LoggingMovieRepository : IMovieRepository {

    private readonly IMovieRepository _repo;
    private readonly ILogManager_log;

    public LoggingMovieRepository (IMovieRepository repo, ILogManager log){
        _repo = repo;
        _log = log;
    }

    Movie GetById(int id) {
        //We log the call
        _log.LogInfo(String.Format("Getting movie {0} from database", id));

        return _repo.GetById(id);
    }
}

And we now have four completely different implementations of IMovieRepository each with it's own unique responsiblity. And the best part? They need to know absolutely nothing of each other. We could even switch the order of operations around by simply changing our structuremap configuration, like so:

For<IMovieRepository>().Use<MovieRepository>();
For<IMovieRepository>().DecorateAllWith<CachingMovieRepository>();
For<IMovieRepository>().DecorateAllWith<LoggingMovieRepository>();
For<IMovieRepository>().DecorateAllWith<AuditingMovieRepository>();

And suddenly the auditing happens before the logging.

To be able to fully utilize this pattern I have composed a simple asynchronous and generic repository interface that looks like this:

public interface IRepository<TEntity>
    {
        Task<TEntity> GetByIdAsync(int id);
 
        IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
 
        IQueryable<TEntity> GetAll();
 
        Task UpdateAsync(TEntity entity);
 
        Task InsertAsync(TEntity entity);
 
        Task DeleteAsync(TEntity entity);
    }

Remember Async methods makes sure your thread is released back to the thread pool instead of waiting for potentially long running operations (such as accessing a database). This can increase the scalability and performance of your application. This combined with an abstract base class forms a solid foundation for dataaccess that can be easily extended with the decorator pattern. Here's the base class:

public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        protected DbSet<TEntity> DbSet;
 
        protected readonly AppDbContext _dbContext;
 
        public BaseRepository(AppDbContext dbContext)
        {
            _dbContext = dbContext;
            DbSet = _dbContext.Set<TEntity>();
        }
 
        public virtual IQueryable<TEntity> GetAll()
        {
            return DbSet;
        }
 
        public virtual async Task<TEntity> GetByIdAsync(int id)
        {
            return await DbSet.FindAsync(id);
        }
 
        public virtual IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
        {
            return DbSet.Where(predicate);
        }
 
        public virtual async Task UpdateAsync(TEntity entity)
        {
            _dbContext.SetModified(entity);
            await _dbContext.SaveChangesAsync();
        }
 
        public virtual async Task InsertAsync(TEntity entity)
        {
            DbSet.Add(entity);
            await _dbContext.SaveChangesAsync();
        }
 
        public virtual async Task DeleteAsync(TEntity entity)
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
            await _dbContext.SaveChangesAsync();
        }
    }

A very rudimentary implementation of the interface, it works for most simple data access scenarios. One thing to note is that I have extended the regular DbContext with a virtual method .SetModified(entity);. This is merely for unit testing purposes as it is otherwise hard to unit test the non virtual Entry() method.

Here's the SetModified method for the sake of completeness:

//This is here only for unit testing purposes
public virtual void SetModified(object entity)
    {
        Entry(entity).State = EntityState.Modified;
    }

There we go, all the plumbing done and over with... Lets say we now actually wanted to create a movie repository and start storing some movies.

Lets start with creating our movie class, a simple POCO object (we'll use Entity Framework code first to create the database).

public class Movie
    {
        public string Name { get; set; }
        public int Length { get; set; }
        public string Description { get; set; }
    }

Alot more should of course go into this class, like Directors, Genres etc. but lets keep it simple for now.

We need to add this as a DbSet to our DbContext class, something like this.

public class AppDbContext : DbContext {
    public DbSet<Movie> Movies { get; set; }
}

And now we just need an implementation of BaseRepository and we're ready to access some data.

public class MovieRepository : BaseRepository<Movie> {
    public MovieRepository(AppDbContext context) : base(context) {
    }
}

Now if we had an MVC controller where we needed to access a Movie and use it as a model we would do something along the lines of this:

public class MoviesController : Controller {

    private readonly IRepository<Movie> _repo;
    
    public MoviesController(IRepository<Movie> repo) {
        _repo = repo;
    }

    public async Task<ActionResult> Index(int id) {
        var model = await _repo.GetByIdAsync(id);

        return View(model);
    }
}

We use constructor injection here to inject an IRepository<Movie> into our controller, this would be populated by Structuremap and could be wrapped by any of our implementations of the IRepository interface. And that's the beauty of it! The controller doesn't even need to know which implementation it will be calling or what it will be doing. All it needs to know is that it will be passed an IRepository dependency and should expect to get a Movie entity from it.