Deciding Where and How to Cache the Data
The fact that you need to do something different from the built-in providers is, of course, the main reason for creating a custom provider for an application block. Therefore, in addition to understanding how to interact with the existing classes in Enterprise Library when you design your provider, you must figure out how to handle the data or resources that your extended application block uses. For the Caching Application Block, this means deciding where and how to store the cached data.
A common requirement for ASP.NET applications is caching the data in a location accessible from all servers and all running instances of the application, especially for application-level data that is not user-specific. Alternatively, you might have a requirement for some specific storage format or technology. In theory, you can cache the data anywhere, using any format that you wish. But bear in mind that you must provide a robust mechanism that meets the aims of the block and imposes sufficient security over the content.
For this example, the choice is custom-format disk files, stored at a location defined when configuring the provider. This location could be on the local machine, or on a network drive. Other approaches that might be suitable, depending on the application's requirements, could include delivering the data to a Web service for remote storage, writing to some otherwise unsupported database system, or even sending it to a remote location through an error-tolerant messaging service.
Remember that the Caching Application Block reads the persisted data only when the application starts
, not every time the application reads data (because it reads it from the in-memory cache), so being able to persist it efficiently is more important than the access time for reading items. You might consider an asynchronous process that takes the data and persists it while allowing the application to continue running, though you would need to ensure that your code is robust and fault tolerant, and can correctly queue cache updates.
Also bear in mind that, because the Caching Application Block reads only from its in-memory cache (and not from the persisted cache) during its lifetime, using a single central cache for multiple instances of the block will not work if you retain a reference to the block in your application. If you run two instances of the ASP.NET example within Visual Studio 2005 or Visual Web Developer, you will see that one instance cannot see cached items from other instance due to the way that the IDE runs the code. However, if you install the example into IIS and run two instances, you will see that they share the cache and can retrieve cached items created by the other instance. This is because, due to the stateless nature of HTTP, each page load creates a new instance of the Caching Application Block - which then loads the current set of cached items from the backing store.
Custom File Caching Provider Design
The custom provider described here is simplified so you can concentrate on the interaction with the Caching Application Block and the overall requirements of Enterprise Library. As you will see, this means that some features are not supported. For example, it does not support cache refresh callbacks, variable cache priorities, and multiple expirations. Instead, it caches all items with the normal priority and with the sliding time expiration policy. It is not difficult to implement these missing features, but does involve quite a lot of extra codein particular for handling all the different expiration object types.
When the Caching Application Block calls the methods of this example provider to cache data, it will create two disk files in a folder specified in the application's configuration. The first is a binary file containing a serialized representation of the cached value; with the name cache-key.cachedata
is the integer cache key value as a string). The second file is the "information" file containing the metadata about the cached itemthe string key name, the date and time the value was last updated, and the expiry period as a sliding time. This file is named cache-key.cacheinfo
is the integer cache key value as a string).
Each cached value uses two files, meaning that adding items to the cache does not involve reading and updating what could be a very large file if all the items were stored in the same file. It also makes it easy to count the number of cached items, and delete individual items (by simply deleting the relevant pair of files).
Building the Custom File Cache Provider
You can create a custom provider in a new project, and compile it into a separate assembly, or you can build the provider within the Enterprise Library solution in Visual Studio and compile it into the existing assemblies. This second option is often easier, because the solution you use already references all the required assemblies and namespaces, and your provider is easy to configure afterwards when you use it in your applications.
Referencing Enterprise Library Assemblies and Namespaces
If you decide to use a new and separate project, you must add references to the following assemblies (located in the %Program Files%\Microsoft Enterprise Library January 2006\bin
folder) to your project:
Then, in your custom provider class, you will generally need to import the following namespaces:
With those namespace references in place, you're ready to write the custom provider class code.