We are working on a large legacy application and we\'re redesigning the business layer and the data layer. We believe that it is a good time to redesign the way cache is han
The MS Patterns and Practices team created Enterprise Library as their response to this question for a host of commone scenarios. EntLib includes Caching as well as Data Access, Validation, Logging, Exception handling, etc. We've used it for years and wouldn't think of starting a new project without it.
http://www.codeplex.com/entlib
As well as the P&P home page, http://msdn.microsoft.com/en-us/practices/default.aspx
This is a big subject, but here are a few suggestions:
In case it helps, I cover this subject in detail in my book: Ultra-Fast ASP.NET.
public T GetFromCache<T>(string key, Func<T> ifKeyNotFoundDelegate)
to ensure that cache is always used the same. [1]Ah well, that covers most of what we do in our website (20GB memcached cluster spread over 20 servers).
[1] By making such a function the only interface to store stuff in cache, you can achieve the following. Let's say I want to use something from the cache, like the result from a function. Normally you would do something like
CacheManager cm = new CacheManager(CacheGroups.Totals);
object obj = cm.GetFromCache("function1result");
if(obj == null)
{
obj = (object)DAO.Foo();
cm.StoreInCache("function1result", obj);
}
return (List<MyEntity>)obj;
By using a different interface you can ensure that users won't make a mistake here.
Like
public T GetFromCache<T>(string key, Func<T> ifnotfound)
{
T obj = this.GetFromCache(key) as T;
if(obj == default(T))
{
obj = ifnotfound.Invoke();
this.StoreInCache(key, obj);
}
return obj;
}
This ensures that
Ergo: less probable that they make a mistake. Furthermore: you get nicer, more clear, code, like:
List<MyEntity> list = new CacheManager(CacheGroups.Total).GetFromCache<List<MyEntity>>("function1result", ()=>DAO.Foo());