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:
What we’re doing here is simply injecting a concrete implementation for
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:
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.
The interface, simplified to one method.
The only concrete implementation that actually does the heavy lifting of getting a movie from the database. Nothing really to see here.
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.
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.
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:
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:
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:
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
Here’s the SetModified method for the sake of completeness:
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).
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.
And now we just need an implementation of BaseRepository and we’re ready to access some data.
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:
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.