Tuesday, January 6, 2015

Caching: Creating a wrapper around MS EntLib Caching


These are the layers through which we have sequential calls:
Client > ServiceImplementation > Manager > Provider > DataSource

A provider may call a datasource directly. Providers can also call Managers to get requested info.

Example:
* EmployeeInformationProvider requires AsianEmployees. Hence it calls EmployeeManager.GetAsianEmployees().
* EmployeeManager.GetAsianEmployees() in turn first tries to get cached asian employees else it  will get from the datasource. Here's the code:
//Inside EmployeeManager.cs  
 public List<Employee> GetAsianEmployees()  
 {  
  return CacheProvider.CachedAsianEmployees();  
 }  
 //Inside CacheProvider.cs  
 public static CachedAsianEmployees()  
 {  
  List<Employee> employees = CacheUtility.RetrieveItem<List<Employee>>("AsianEmployeesPolicy", "AsianEmployees");  
 }
...where
AsianEmployeesPolicy = policy name
AsianEmployees = key name  

Now the CacheUtility class:
public static T RetrieveItem<T>(string policy, string keyname)  
 {  
   T res = default(T);  
      //create a tag named '<policy name="AsianEmployeesPolicy">' in config file.  
      //inside that place a provider tag which has the filename and assembly. It will have description and expiry time subtags  
   //read policy tag from config file  
   //CachingPolicy is a class with properties such as Name, ProviderInfo.  
   CachingPolicy p = CachingPolicyUtility.GetPolicy(policy);  
   if (p != null)  
   {  
     //inner implementation is upto you. Basically what this code does is initiate an activator.getinstance of the full file name with assembly that  
      //we had provided in the policy tag in our config.  
      //that provider file has certain methods like RetrieveItem which we need to invoke  
      //providers can be SlidingExpirationCacheProvider, StaticExpirationCacheProvider or SqlDependencyCacheProvider all having base type CachingProvider  
      CachingProvider provider = (CachingProvider)ProviderLoader.LoadProvider(p.ProviderInfo, typeof(CachingProvider));  
      res = (T)provider.RetrieveItem(keyname);  
   }   
   return res;  
 }  

Lets see an implementation of SlidingExpCacheProvider
Inherit some base class with operations such as StoreItem, RetrieveItem, ExpiryTime property in SlidingExpCacheProvider like SlidingExpCacheProvider: BaseCacheProvider

public class SlidingExpCacheProvider: BaseCacheProvider  
 {  
 void Init()  
 {  
 //get expiry time etc..in some private variable to use in GetExpTime property here ..  
 //also set a default time if exp time was not provided...  
 }  
 //override as necessary or stick to default implementation  
 public override object RetrieveItem(string key)  
 {  
 //CacheManager is from MS.EntLib.Caching  
   CacheManager cacheManager = CacheFactory.GetCacheManager();  
   return cacheManager[key];  
 }  
 public override void StoreItem(string key, object item)  
 {  
   double time = Convert.ToDouble(_exptime, CultureInfo.InvariantCulture);  
   //CacheManager is from MS.EntLib.Caching  
   CacheManager cacheManager = CacheFactory.GetCacheManager();  
   cacheManager.Add(key, item, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromMinutes(time)));  
 }  
 }

StaticExpCacheProvider is very similar to SlidingExpCacheProvider with the following differences:
*//Add item to cache 
cacheManager.Add(key, item, CacheItemPriority.Normal, null, new AbsoluteTime(DateTime.Now.AddSeconds(time)));
* Sliding exp: Cached element will expire after specified expiry time elasped after last access.
* Static: Element expires after the specified exp time. 

No comments :