I have an MVC-based site, which is using a Repository/Service pattern for data access. The Services are written to be using in a majority of applications (console, winform, and web). Currently, the controllers communicate directly to the services. This has limited the ability to apply proper caching.
I see my options as the following:
- Write a wrapper for the web app, which implements the IWhatEverService which does caching.
- Apply caching in each controller by cache the ViewData for each Action.
- Don't worry about data caching and just implement OutputCaching for each Action.
I can see the pros and cons of each. What is/should the best practice be for caching with Repository/Service
Based on answer provided by Brendan, I defined a generic cached repository for the special case of relatively small lists that are rarely changed, but heavily read.
1. The interface
2. Normal/non-cached repository
}
3. Generic cached repository is based on non-cached one
Using a DI framework (I am using Ninject), one can easily define if a repository should be cached or not:
So, reading from cached repositories is done without knowing about the caching. However, changing them requires to inject from
ICacheRepository<>
and calling the appropriate methods.Steve Smith did two great blog posts which demonstrate how to use his CachedRepository pattern to achieve the result you're looking for.
Introducing the CachedRepository Pattern
Building a CachedRepository via Strategy Pattern
In these two posts he shows you how to set up this pattern and also explains why it is useful. By using this pattern you get caching without your existing code seeing any of the caching logic. Essentially you use the cached repository as if it were any other repository.
Check my implementation of caching service:
How to cache data in a MVC application
(i don't want to repeat answer here...)
Fell free to comment!
The easiest way would be to handle caching in your repository provider. That way you don't have to change out any code in the rest of your app; it will be oblivious to the fact that the data was served out of a cache rather than the repository.
So, I'd create an interface that the controllers use to communicate with the backend, and in the implementation of this I'd add the caching logic. Wrap it all up in a nice bow with some DI, and your app will be set for easy testing.