Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Exploring Caching: Using Caching Application Enterprise Library 4.1

4.84/5 (52 votes)
10 Jan 2010CPOL14 min read 247K  
This article describes the use of Caching Application Block - Enterprise Library 4.1.

Table of Contents

Introduction

Caching is one of most important factors if we think about application performance. Most applications need a caching implementation to improve performance. The Caching Application Block provides a flexible and extensible caching framework with a set of APIs that can be used at any layer of an application. It supports in-memory, database, or isolated storage for storing cached data. We can use it in web applications as well as Windows applications. Implementing caching using the Caching Application Block improves the performance of applications as well as reduces development time and cost. This application block provides all kinds of functions like adding, removing, and managing the expiration of cache. In this article, I have explained how we can use the Caching Application Block of Enterprise Library 4.1 in an ASP.NET Web application. But as I said earlier, the Caching Application Block is very generic and can be used in different applications without changing a single line of code. In other words, we can say the Enterprise Library Caching Application Block provides a ready to use caching framework. Hope this article will help all of you. Please provide your valuable suggestions and feedback to improve my article.

Where can the Caching Application Block be used?

The Enterprise Library Caching Application Block is a ready to use caching framework that can be used in various applications like:

  • ASP.NET Web applications
  • Windows Forms
  • Console
  • Windows Service
  • Enterprise Services
  • Web Service

This caching application block has in-built features like inserting an item into cache, remove from cache, cache expiration settings, etc. This is extensible as well as per your requirement.

In this article, I have a demo code which is an ASP.NET Web Application.

Installing Enterprise Library 4.1

First of all, we need to install Enterprise Library before we start working with any of the application blocks. As of now, the latest version of Enterprise Library is 4.1. This article is based on the same version. You can download and install Enterprise Library easily from Enterprise Library 4.1-October 2008.

Microsoft Enterprise Library is a collection of reusable application blocks designed to assist software developers with common enterprise development challenges. This release includes caching, cryptography, data access, exception handling, logging, policy injection, security, validation, and unity.

Development Environment

For demonstrating the article and developing the sample code, I have used the below environment:

  • Windows Vista Home Premium
  • Visual Studio 2010 Professional - Beta 2
  • .NET Framework 4.0
  • Enterprise Library 4.1

You can develop the same in your own environment. You can check the system requirements for Enterprise Library 4.1 here.

Using Enterprise Library Configuration Manager

Enterprise Library's API is based on an XML configuration. The application configuration file contains all related information regarding application blocks. As this is an XML configuration, we can do all kinds of manual changes in the file but it’s quite difficult to remember all the configuration and properties. Microsoft provides the Enterprise configuration UI console to configure the application block using a UI.

After installing Enterprise Library 4.1, you can find the Enterprise Library Configuration Manager in the Bin directory of your installed location. In my case, it is in "C:\Program Files (x86)\Microsoft Enterprise Library 4.1 - October 2008\Bin". Run EntLibConfig.exe. Or you can go to Start > Select Program Files > Microsoft Patterns and Practices > Enterprise Library >Enterprise Library Configuration. The following screen will appear:

Image 1

Configure Caching Application Block

Now click on File > Open application. Select the "web.config" of your ASP.NET web application.

Image 2

By default, Enterprise Library configuration has a Data Access Application Block setting added. We can easily remove any configuration settings by using right click > Remove.

Now we can add a "Caching Application Block" using right click on Root > New > Caching Application Block.

Image 3

A new configuration section "Caching Application Block" will be automatically added with the configuration File.

Image 4

Save the configuration in Configuration Manager. Now open the web application and check the web.config file for changes. You will find the below Config section has been added in the web.config file after adding the Caching Application Block using the Enterprise Application Manager.

Image 5

Using the Caching Application Block

Adding Reference

As the caching application block is a predefined set of code and is defined in a framework, we need to add some reference to our application. These are Microsoft.Practices.EnterpriseLibrary.Caching.dll and Microsoft.Practices.EnterpriseLibrary.common.dll. These two are sufficient for using the Caching Application Block.

Image 6

After adding a reference, we have to add a namespace for using the Caching Application Block. These are:

C#
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Common;

This is all about adding references and namespaces. Now let’s have a look at how we can do all kinds of caching operations like insert data into cache, remove from cache, display data from cache, cache expiration, etc.

Before doing any kind of caching operation, we need to initialize the CacheManager object.

Initialize Cache Manager

ICacheManager is the main interface between our application and the Caching Application Block. To create an instance of a CacheManager object, the application uses the CacheFactory class, which in turn uses the CacheManagerFactory class. The CacheManagerFactory class creates all the internal classes needed to implement a CacheManager object.

C#
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();

GetChcheManager has an overloaded method; by default, it returns the default CacheManger instance. We can also specify the cache manager name which is specified in the configuration file like:

C#
ICacheManager _objCacheManager = CacheFactory.GetCacheManager("MyCacheManager");

The GetCacheManager() method will always return the same instance of the cache manager whenever we call it from the application. So if we are using multiple cache managers in our application, we need to provide the name of the cache manager in CacheFactory.GetCacheManager(<name>);.

Insert Item to Cache

Now we have an instance of CacheManager. The CacheManager provides an Add() method to add a new CacheItem to the cache. By default, it takes two arguments: String Key and Object Value.

Below is a sample code snippet to show how to add a CacheItem to the cache:

C#
//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
//Add a new CacheItem to Cache
_objCacheManager.Add("Name", "Abhijit");

Where Name is my key and "Abhijit" is the object value. This is a very simple example. We can even store a complex object inside the cache. Have a look at the example below with a simple Student class:

C#
/// <summary>
/// Student Class
/// </summary>
public class Student
{
    #region PrivateVariable
    //Studnet Name
    private string name;
    //Student Roll
    private int roll;
    #endregion PrivateVariable

    #region PrivateProp
    private int Roll
    {
        get
        {
            return roll;
        }

        set
        {
            roll = value;
        }
    }
    private string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
        }
    }
    #endregion PrivateProp

    /// <summary>
    /// Student Constructor
    /// </summary>
    /// <param name=""roll"" />Roll
    /// <param name=""name"" />Name
    public Student(int roll, string name)
    {
        this.Roll = roll;
        this.Name = name;
    }
}

The Student class code is very simple where I am using only one parameterized constructor to create an instance of a student. The code below shows how we can store a student object in the cache.

C#
//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
// Create Instance of Student Class
Student _objStud = new Student(10, "Abhijit");
// Add Studnet Object as Cache Item
_objCacheManager.Add("Student", _objStud);

As caching is used to store data in a large scale, we can store a DataSet, DataTable as a CacheItem in the cache. The example below shows how to store a DataSet in a CacheItem.

C#
_objCacheManager.Add("LargeData", _objDataSet);

Till now I discussed the basic versions of the Add() method which has only two arguments. As I have already mentioned, the Add() method has one more overloaded method to extend the caching functionality into a greater extend. These overloaded methods have five arguments: key, value, scavengingPriority, refreshAction, and expirations.

Image 7

Key and Value are same as described earlier. Now we have three new things:

  • CacheItemPriority
  • ICacheItemRefreshAction
  • ICacheItemExpiration[]

The CacheItemPriority enumeration allows you to specify the priority level for the cached items. By default it is Normal. ICacheItemRefreshAction is used when you want to perform something when refreshing cache items from cache collections. ICacheItemExpiration allows the end user to implement their own cache item expiration schema. We can set them as null if we want to omit them. I have explained each of them in detail in a later section.

Remove Item from Cache

Removing an item from cache is very easy to implement. CacheManager provides a Remove() method to remove a CacheItem from cache. This method has no overloaded method and takes only a single argument Key. If the key exists, the CacheItem will be removed automatically from CacheItems, otherwise this method will do nothing.

C#
//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
//Remove Item From Cache
_objCacheManager.Remove("Name");

This is the same for all types of CacheItems. We saw earlier how we store a DataSet in the cache. If we want to remove that, we only have to do:

C#
_objCacheManager.Remove("LargeData");

Note: We have to make sure that for all keys, the instance of CacheManager is the same.

Remove All Items From Cache

We can remove all items from cache using the Flush() method of CacheManager.

C#
_objCacheManager.Flush();

During this operation, if an error occurs, cache items will remain unchanged.

Check if Key Exists or Not

If we are using multiple CacheManagers, or if we want to check whether the key belongs to a particular cache collection or not, we can use the Contains() method of CacheManager.

C#
if(_objCacheManager.Contains("Name"))
{
  //Do something
}
else
{
 // Do Something
}

Retrieve Item From Cache

After adding an element into a cache, the next thing we need to do is to retrieve the cache element from the cache collection. The CacheManager provides a method called GetData(). GetData() accepts only one argument Key and returns the cache data. But when retrieving the cache element, we have to make sure we are type casting the object in proper type. For example, if we have stored a DataSet as an object in cache, during retrieval, we have to make sure we are doing the same type casting.

C#
//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
// Create Instance of Student Class
Student _objStud = new Student(10, "Abhijit");
// Add Studnet Object as Cache Item
_objCacheManager.Add("Student",_objStud);

// Check If Key is in Cache Collection
if(_objCacheManager.Contains("Student"))
{
  // Retreive Cached Student Data
  Student _objCachedStudent = 
    (Student)_objCacheManager.GetData("Student");
}

Caching Expiration

Microsoft Caching Application Block provides great use of the caching expiration functionality. For that, we need to add the namespace below:

C#
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

Adding the namespace will provide us the below classes to implement the expiration of caching using the Application Block.

  • AbsoluteTime
  • ExtendedFormat
  • ExtendedFormatTime
  • FileDependency
  • NeverExpired
  • SlidingTime

AbsoluteTime

Absolute time defines the lifetime of a cache item by specifying the absolute time for an item to expire from the cache item collection. Absolute expirations are specified in full-time format (hh:mm:ss). The object will expire from the cache at the specified time:

For example:

C#
AbsoluteTime _AbsoulteTime = new AbsoluteTime(TimeSpan.FromHours(1));
_objCacheManager.Add("Student", _objStud, 
    CacheItemPriority.Normal, null, _AbsoulteTime);

ExtendedFormat and ExtendFormatTime are quite similar with AbsoluteTime configuration. I am not going into details on these two. Let us start with FileDependency.

FileDependency

File-based dependency invalidates a particular cache item when a file(s) on the disk changes. This is quite helpful when we want to update cache data if there are some changes in files or database.

C#
FileDependency _objFileDependency=new FileDependency("MyFile.XML");
_objCacheManager.Add("Student", _objStud, CacheItemPriority.Normal, null, _objFileDependency);

As per the given example, if there is any change in "MyFile.xml", then _objStud will be removed from the cache collection. Sometimes it is very useful when we want to update cache data on file changes.

NeverExpired

If we set the caching expiring policy as never expire, then data will be stored in the cache collection unless and until we use CacheManager.Remove() to remove the cache item. When we use the CacheManager.Add() method with only a key and value argument, the cache object is set to never expire mode.

Sliding

Sliding resets the time for the item in the cache to expire on each request. This is useful when an item in the cache is to be kept alive as long as requests for that item are coming in from various clients. This means the item expires after the specified time has elapsed from when the item was last accessed. The default time is 2 minutes.

C#
SlidingTime _objSlidingTime = new SlidingTime(TimeSpan.FromMinutes(5));
_objCacheManager.Add("Student", _objStud, CacheItemPriority.Normal, null, _objSlidingTime);

Use Multiple Expariation Policy

I have already discussed the CacheManager.Add() method which has one more overloaded method that takes five arguments. One of the arguments is an ICacheItemExpiration. If you look at the details, the type of argument is params, so using that, we can set the multiple expiration policy for a cache collection. Below is a sample example:

C#
//Creating Absolute Time Expiration
AbsoluteTime _AbsoulteTime = new AbsoluteTime(TimeSpan.FromHours(1));
//Creating FileDependecy Object
FileDependency _objFileDependency=new FileDependency("MyFile.XML");
// Using ICacheItemExpiration To Set multiple Cache Expiration policy
_objCacheManager.Add("Student", _objStud, CacheItemPriority.Normal, 
   null, new ICacheItemExpiration[] { _AbsoulteTime, _objFileDependency });

So _objStud will remove from the cache collection based on the two expiration policies.

Implementing ICacheItemRefreshAction

ICacheItemRefreshAction is the part of the RefreshAction parameter of the CacheManager.Add() method. The refreshAction parameter allows for passing in an object that will perform some actions to update the cached object when it has expired. This is quite helpful if we want to perform some operations during cache expiration.

C#
public class CacheLogPolicy : ICacheItemRefreshAction
{
    // Implement Referesh Method of interface ICacheItemRefreshAction
    public void Refresh(string removedKey, object expiredValue, 
           CacheItemRemovedReason removalReason)
    {
      // Log The Information Or We can do some other stuff also
    }

}

Now set the parameter of the refresh action in the CacheManager.Add() method as follows:

C#
_objCacheManager.Add("Student", _objStud, 
    CacheItemPriority.Normal, new CacheLogPolicy(),null);

Data Storage in the Caching Application Block

Each cache manager can either be configured to store data only in memory or also store data in persistent storage. Caching Application Block provides the following storage locations:

  • In Memory / Null Backing Store
  • Database Cache Storage
  • Isolated Cache Storage
  • Custom Cache Storage

In Memory / Null Backing Store

The default storage location for the Caching Application Block is in-memory which sets the backing store value to nullbackingstore. The configuration setting for null storage is: backingStoreName="Null Storage".

Database Cache Storage

Data cache storage uses a database to store caching data. This cache data is persistent data. Generally another Enterprise Application Block called "Data Access Application Block" is used to store caching data in a database. We can add a "Data Storage" by "Cache Manger" > New > Database Cache Storage.

Image 8

When we add a data cache store using Enterprise Library configuration, this will automatically add a "Data Cache Storage" with the Cache Manager and a "Data Access Application Block".

Image 9

Now we have to configure the data application block to store database cache data. Configuration of Data Application Blocks means providing the database server name, connection string, etc. I will write a separate article to show how to use "Data Access Application Block" to store "Database Cache Data" very soon. If you are familiar with "Data Access Application Blocks" you can easily implement it.

Isolated Cache Storage

For using Isolated Storage, we need to provide the "Partition Name" in the configuration. The partition name will identify the storage area for the Cache Manager inside Isolated Storage.

Image 10

I mentioned Partition Name as "CacheIsolated". The diagram below shows the corresponding web.config entry:

Image 11

Generally Isolated Storage is useful when we need data to be persisting and the amount of data is less.

Custom Cache Storage

Apart from in-memory, database, and Isolated Cache storage, we can create our own custom cache storage to persist cached data. We can add "Custom Cache Storage" similar to database or Isolated Cache. We need to create a custom Provider that implements the IBackingStore Interface.

Common Configuration for Caching Application Block

For using the Caching Application Block, we need to know about a few common configuration settings. These are:

  • expirationPollFrequencyInSeconds
  • maximumElementsInCacheBeforeScavenging
  • numberToRemoveWhenScavenging

These common settings can be found in the Enterprise Library Configuration Manager as well as in the application web.config.

Image 12

expirationPollFrequencyInSeconds

Expiration pool frequency is used to check the CacheItems in the hashtable to see if an item has expired. All the expiration policy in the Caching Application Block is handled by BackgroundScheduler. The default value of pool frequency is 60 seconds.

maximumElementsInCacheBeforeScavenging

Scavenging means that the cache attempts to remove infrequently used or unimportant items if memory becomes low. As the name suggests, this setting is used to set the scavenging policies. This defines the maximum number of elements in the cache before the item should be scavenged from cache. By default, it is "1000".

numberToRemoveWhenScavenging

The number of remove items defined in the numberToRemoveWhenScavenging setting will be removed from cache from during the scavenging process. The default value for the Remove Scavenging item from cache is "10".

Summary

This article describes the use of the Caching Application Block using Enterprise Library 4.1. Though it is not a new topic, I have tried my best to explain the entire important thing related with Caching Application Block. This article is mostly based on theoretical concepts. In the next article, I will explain some practical implementations of the Caching Application Block like Database Storage Caching Application Block.

Hope this article has helped you to start up with Caching Application Block. Please provide your valuable suggestions and feedback to improve the article.

Reference and Further Study

History

  • Initial post - 10 Jan 2010.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)