As a follow up to my post on creating a Web Session Management and Centralization Class, I thought I would also touch on one method of presentation level caching. Caching, as well all know, stores a local version of some data closer to the actual requestor making the call, whether it is in the BLL, the presentation, or even page/control specific. Caching can be a significant boost to performance and is fairly easy to implement. Additionally, there are several types of caching, such as image, page, custom, etc. In this brief example, we’re going to explore a custom implementation of caching to minimize trips to the database.
When Would I Use This?
In my opinion the ideal candidates for presentation level caching are things like dropdown lists which are dynamically pulled from the database. I’ve been working on a project which utilizes several dropdowns throughout the application, and each one is to be administered dynamically. This means for each page, I may have several calls to simply setup the page and populate the dropdowns.
In this application, I’m calling a business logic layer which calls down to the data access layer and finally to the database. We can minimize the amount of calls to the database by instead of calling directly to the business layer, call our WebCacheManager class, which is going to first check if the data exists in local cache, or if it needs to make a call to retrieve the data. If the call is made down to the business layer, the results are then stored in the local cache until either the cache expires based on an absolute date/time or a dependent file (acting as a trigger) is modified.
The external file, located in _cacheDependencyFilePath in the following code is a textfile, which can be manually or programmatically modified to expire the cache without having to reset IIS or wait out the expiration time period. The following code sets up a helper class which could sit on the presentation (web application), and be called to retrieve cached data back very quickly.
WebCacheManager
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Common.Entities.Complaints; //This is just a reference to my business entities project using System.Web.Caching; using System.IO; namespace UI.ComplaintsWeb.Code { public class WebCacheManager { /// /// A reference to the current context cache. /// private Cache _cache; /// /// A filepath to the cachedependency file which triggers expiration of cache. /// private string _cacheDependencyFilePath; /// /// The absolute date/time of cache expiration. /// private DateTime _expirationDate; public WebCacheManager() { _cache = HttpContext.Current.Cache; _cacheDependencyFilePath = Path.GetFullPath("../CacheDependency.txt"); _expirationDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59); } public InspectionType[] GetInspectionTypes() { InspectionType[] data; string cacheKey = "InspectionTypes"; if (_cache[cacheKey] != null) { //Get data from cache data = _cache[cacheKey] as InspectionType[]; } else { //Get data from database data = WebHelper.ComplaintsLogic.GetInspectionTypes(); //Assign to cache _cache.Add(cacheKey, data, new CacheDependency(_cacheDependencyFilePath), _expirationDate, System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); } return data; } } }
Fancy, How Do I Call It?
No sweat, let’s imagine we’re binding to a DropDownList called “InspectionTypeList”, instead of your typically business call (or direct DB call if you’re into that sort of thing, and you probably shouldn’t be, but that’s another topic); simple use the following similar syntax:
var cacheManager = new WebCacheManager(); //Inspection Types InspectionTypeList.DataSource = cacheManager.GetInspectionTypes(); InspectionTypeList.DataBind();
Not too much to it. If you have any questions on how the WebCacheManager is being used, or suggestions on improvements, please leave a comment below. Don’t be shy, you know you want to comment.