The great thing about abstract repositories is that you can use the Decorator pattern to implement cross-cutting issues like caching.
As an example, given the IMyRepository interface, you can create a MyCachingRepository similar to this pseudocode:
public class MyCachingRepository : IMyRepository { private readonly IMyRepository repository; public MyCachingRepository(IMyRepository repository) { if(repository == null) { throw new ArgumentNullException("repository"); } this.repository = repository; } public Foo SelectFoo(int id) { Foo foo = ...
In this example, GetFoo is defined by IMyRepository. Please note that the decorated repository is called only if the item is not found by the cache.
This follows the principle of a single replacement , as the actual caching implementation may focus on retrieving and storing data, while Decorator caching may focus on caching. This allows you to change two independently of each other.
In our current project, we used this approach, and what is nice is that we could do this as an afterthought, without even touching the original repositories. This is in the spirit of the Open / Closed principle .
Mark seemann
source share