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:
Configure Caching Application Block
Now click on File > Open application. Select the "web.config" of your ASP.NET web application.
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.
A new configuration section "Caching Application Block" will be automatically added with the configuration File.
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.
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.
After adding a reference, we have to add a namespace for using the Caching Application Block. These are:
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.
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:
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:
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
_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:
public class Student
{
#region PrivateVariable
private string name;
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
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.
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
Student _objStud = new Student(10, "Abhijit");
_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
.
_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
.
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.
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
_objCacheManager.Remove("Name");
This is the same for all types of CacheItem
s. We saw earlier how we store a DataSet
in the cache. If we want to remove that, we only have to do:
_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
.
_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 CacheManager
s, 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
.
if(_objCacheManager.Contains("Name"))
{
}
else
{
}
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.
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
Student _objStud = new Student(10, "Abhijit");
_objCacheManager.Add("Student",_objStud);
if(_objCacheManager.Contains("Student"))
{
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:
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:
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.
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.
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:
AbsoluteTime _AbsoulteTime = new AbsoluteTime(TimeSpan.FromHours(1));
FileDependency _objFileDependency=new FileDependency("MyFile.XML");
_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.
public class CacheLogPolicy : ICacheItemRefreshAction
{
public void Refresh(string removedKey, object expiredValue,
CacheItemRemovedReason removalReason)
{
}
}
Now set the parameter of the refresh action in the CacheManager.Add()
method as follows:
_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.
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".
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.
I mentioned Partition Name as "CacheIsolated". The diagram below shows the corresponding web.config entry:
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.
expirationPollFrequencyInSeconds
Expiration pool frequency is used to check the CacheItem
s 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.