Many ASP.NET applications utilize the System.Web.Caching.Cache in some way. While it offers a pretty simple Dictionary-like API that your app can start using immediately, I typically create a combined ātell-donāt-askā wrapper around it ā which has some additional architectural benefits as well.
A very common usage of the Cache API can be seen below, but there are a few initial problems I have with it:
Ā
public ActionResult Bad()
{
var firstVisit = HttpContext.Cache.Get("FirstVisit") as DateTime?;
if(firstVisit == null)
{
firstVisit = DateTime.Now;
HttpContext.Cache.Insert("FirstVisit", firstVisit, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
}
return View("Index", firstVisit.Value);
}
Ā
The wrapper I create is used below. Itās nothing revolutionary, but does try to cut down on the redundancy, while adding a few features as well. The following code functions exactly the same as the code above.
public ActionResult Index()
{
var firstVisit = _cache.Get(CacheScope.User, "FirstVisit", TimeSpan.FromMinutes(1), () => DateTime.Now);
return View(firstVisit);
}
The three biggest changes are:
Aside from these API usage changes we also get 2 big architectural advantages:
You may notice that our controller still has intimate knowledge of our caching strategy: duration, scope, the string-based key, etc. This code-duplication lightning-rod could easily be copy-pasted around. One possible way to solve this would be to create something like the following AppCache.
/// <summary>
/// This class demonstrates fully abstracting the details of your caching strategy and could serve as the single entry point for cached data
/// </summary>
public static class AppCache
{
public static ICache InternalCache = new HttpCache();
public static DateTime UsersFirstVisit = InternalCache.Get(CacheScope.User, "FirstVisit", TimeSpan.FromMinutes(1), () => DateTime.Now);
}
public ActionResult FullyAbstracted()
{
var firstVisit = AppCache.UsersFirstVisit;
return View("Index", firstVisit);
}
Now we are completely free to change the caching strategy of our application in a single place.
Rather than pasting the full source here, I will be publishing it along with a sample project at https://mvcgrabbag.codeplex.com
Ā
Leave a Comment