Tuesday, March 4, 2008

Enterprise Library 3.1 - Caching Application Block (Part 1)

In the previous article, I have explained how the Data Access Application Block can aid in accessing a back-end data store. It is always good to have data that will not disappear when a computer is shut off; the actual task of storing data can hinder performance. This is where the Enterprise Library Caching Application Block helps the developer. The caching block lets developers incorporate a local cache in their applications. It supports both an in-memory cache and, optionally, a backing store that can either be the database store or isolated storage. The application block can be used without modification; it provides all the needed functionality to retrieve, add, and remove cached data.

Caching can offer the following benefits:

Performance: When a local cache of relatively static data is available, an application no longer needs to deal with the overhead of making a call to a data store to retrieve the data.
Scalability: Storing information in a cache helps save resources and increases scalability as the demands on the application increase.
Offline availability: Caching can be very useful in offline smart client applications. The application may be able to survive system failures such as network latency, Web service problems, and hardware failures if the data is stored in the Cache.

Core Classes and Interfaces of the Caching Application Block

The Caching Application Block is composed of a series of core classes and interfaces that provide the caching functionality. The following are the core classes and interfaces of the Caching Application Block:
CacheManager class
CacheFactory class
BackgroundScheduler class
IBackingStore interface
ICacheItemExpiration interface
ICacheItemRefreshAction interface
IStorageEncryptionProvider interface

We will try to look into each of these classes and interfaces and understand what can be achieved by these classes.

The figure below shows the interrelationships between the key classes in the Caching Application Block.

Looking into the CacheManager and CacheFactory class

The CacheManger class is through which you interact with in your application. This singleton instance uses the CacheFactory class to create a single instance for each unique name as defined in the configuration file. Once the CacheManager instance has been created you can start creating and removing cached items from the instance. You can use the GetCacheManager method of the CacheFactory class to get the instance of the CacheManager object.

Adding items into the Cache.

Adding items into the cache is done by using the Add method of the CacheManager class. This is an overloaded method with two signatures.

public void Add(string key, object value, CacheItemPriority scavengingPriority, ICacheItemRefreshAction refreshAction, params ICacheItemExpiration[] expirations);

public void Add(string key, object value);

The Add method that only allows the key and value parameters to be specified will force the cached object to never expire and set the scavenging priority to normal. If you call the Add method with a key value that already exists within the named CacheManager instance, the CacheManager class will first remove the existing item, and then add the new one that was specified.

The scavengingPriority parameter determines how the scavenging background process will prioritize what items will be removed first during the scavenging process. The scavenging priorities are high, normal, low, and not removable. Cached objects with a low priority will be scavenged before cached objects with a normal or high priority. Normal priority cached objects are scavenged before high priority cached objects. Cached objects that have a scavenging priority of not removable will never be scavenged by the scavenging process.

The refreshAction parameter allows for passing in an object that will perform some action to update the cached object when it has expired. This can be very handy if an application is persisting the cached data to some backing store and is shut down for maintenance. When the application is brought back online, items will then be expired and allowed to be refreshed based on the implementation of the ICacheItemRefreshAction that was originally passed in.

The expiration policy parameters are rules that determine when a cached item should be expired from the cache. Since the params keyword is used, it is possible to specify more than one expiration policy per cached object.

Retrieving items from the Cache

You can use the GetData method or the indexer of the CacheManager class for retrieving Cached items.

Removing Cached Items

The Remove method allows you to remove a single cached object based on the key that is passed in. The Flush method will remove all cached objects from the CacheManager instance.

Looking into BackgroundScheduler class

The BackgroundScheduler class manages the life of cached objects in a background thread of the application domain. This includes expiring cached objects based on the expiration policies and scavenging stale cached objects that have not been accessed for an extended amount of time. The BackgroundScheduler object periodically monitors the lifetime of items in the cache. When an item expires, the BackgroundScheduler object first removes it and then, optionally, notifies the application that the item was removed. At this point, it is the responsibility of the application to refresh the cache.

The IBackingStore Interface

The IBackingStore interface provides the interface that the Cache object will use to store the cached objects in a persisted location.

The IStorageEncryptionProvider Interface

This interface provides the interface to protect the Cache data when it is stored to persistence storage. This interface exposes the Encrypt and Decrypt methods for achieving the functionality. The Caching application Block provides a symmetric cryptography provider that allows the use of the Cryptography Application Block to determine how to encrypt and decrypt data. It is possible to provide your own encryption solution by implementing the IStorageEncryptionProvider interface and supplying the necessary configuration support.

In the Next series of this article, I will explain how to use the Caching Application Block in your applications.

1 comment:

Michael Barton said...

Nice article. It has a great deal of information regarding CAB. However, I must mention that CAB’s in-process and standalone nature makes it hard to scale and affects its reliability. The link provided throws more light on the Caching Application Block, its drawbacks and fixes.