1. What Does the Caching Block Do?
The Caching Application Block provides high-performance and
scalable caching capabilities, and is both thread safe and exception
safe. It caches data in memory, and optionally maintains a synchronized
backing store that, by default, can be isolated storage or a database.
It also provides a wide range of expiration features, including the use
of multiple expiration settings for cached items (including both
time-based and notification-based policies).
Even better, if the cache locations are not suitable for your
requirements, or the caching mechanism doesn't do quite what you want in
terms of storing or retrieving cache items, you can modify or extend it.
For example, you can create your own custom expiration policies and
backing store providers, and plug them in using the built-in extension
points. This means that you can implement caching operations throughout
your applications that you access from code using a single simple
API.
On top of all that, the caches you implement are configurable at
design time and run time, so that administrators can change the caching
behavior as required both before and after deployment. Administrators
can change the backing store that the caching mechanism uses, configure
encryption of the cached contents, and change the scavenging
behavior—all through configuration settings.
One of the main factors that can affect application performance
is memory availability. While caching data can improve performance,
caching too much data can (as you saw earlier) reduce performance if
the cache uses too much of the available memory. To counter this, the
Caching block performs scavenging on a fixed cycle in order remove
items when memory is in short supply. Items may be removed from the
cache in two ways:
-
When they expire. If you
specify an expiration setting, the item is removed from the cache
during the next scavenging cycle if they have expired. You can
specify a combination of settings based on the absolute time,
sliding time, extended time format (for example, every evening at
midnight), file dependency, or never. You can also specify a
priority, so that lower priority items are scavenged first. The
scavenging interval and the maximum number of items to scavenge on
each pass are configurable.
-
When they are flushed. You
can explicitly expire (mark for removal) individual items in the
cache, or explicitly expire all items, using methods exposed by
the Caching block. This allows you to control which items are
available from the cache. The scavenging mechanism removes items
that it detects have expired and are no longer valid. However,
until the scavenging cycle occurs, the items remain in the cache
but are marked as expired, and you cannot retrieve them.
The difference is that flushing might remove valid cache items to make space for more frequently used items,
whereas expiration removes invalid and expired items. Remember that
items may have been removed from the cache by the scavenging mechanism
even if they haven't expired, and you should always check that the
cached item exists when you try to retrieve and use it. You may choose
to recreate the item and re-cache it at this point.
If you have data that is relatively volatile, is updated
regularly, or is valid for only a specific time or interval, you can
use a time-based expiration policy to ensure that items do not remain
in the cache beyond their useful valid lifetime. You can specify how
long an item should remain in the cache if not accessed (effectively
the timer starts at zero again each time it is accessed), or specify
the absolute time that it should be removed irrespective of whether it
has been accessed in the meantime.
If the data you cache depends on changes to another resource,
such as a disk file, you can improve caching efficiency by using a notification-based
expiration policy. The Caching block contains an expiration provider
that detects changes to disk files. You can create your own custom
expiration policy providers that detect, for example, WMI events,
database events, or business logic operations and invalidate the
cached item when they occur.
2. How Do I Configure the Caching Block?
Like all of the Enterprise Library application blocks, you start
by configuring your application to use the block To configure the
Caching block, you add the Caching Settings section to the tool, which
adds a default cache manager. The cache manager exposes the caching API
and is responsible for manipulating the cached items. You can add more
than one cache manager to the configuration if you want to implement
multiple caches, or change the default cache manager for a custom one
that you create. For example, you may decide to replace it with a custom
or third party cache manager that supports distributed caching for a Web
farm or application farm containing multiple servers.
You can
see the four cache managers we use, with the section for the EncryptedCacheManager
expanded to show its property settings.
For each cache manager, you can specify the expiration poll frequency
(the interval in seconds at which the block will check for expired items
and remove them), the maximum number of items in the cache before
scavenging will occur irrespective of the polling frequency, and the
number of items to remove when scavenging the cache.
You can also specify, in the configuration properties of the
Caching Application Block root node, which of the cache
managers you configure should be the default. The Caching block will use
the one you specify if you instantiate a cache manager without providing
the name of that cache manager.
The cache manager caches items in memory only. If you want to
persist cached items across application and system restarts, you can
add a persistent backing store to your configuration. You can specify
only a single backing store for each cache manager (obviously, or it
would get extremely confused), and the Caching block contains
providers for caching in both a database and isolated storage. You can
specify a partition name for each persistent backing store, which
allows you to target multiple cache storage providers at isolated
storage or at the same database.
If you add a data cache store to your configuration, the
configuration tool automatically adds the Data Access Application
Block to the configuration. You configure a database connection in the
Data Access block configuration section, and then select this
connection in the properties of the data cache store provider.
You can add a provider that implements symmetric storage
encryption to each persistent backing store you configure if you want
to encrypt the stored items. This is a really good plan if you must
store sensitive information. When you add a symmetric storage
encryption provider to your configuration, the configuration tool
automatically adds the Cryptography Application Block to the
configuration.
You configure a symmetric cryptography provider in the
Cryptography block configuration section. You can use the Windows Data
Protection API (DPAPI) symmetric provider, or select from other
providers such as AES, Triple DES, and Rijndael. F
Note
Note that the Caching Application Block does not
encrypt data in the in-memory cache, even if you configure
encryption for the associated backing store. If it is possible that
a malicious user could access the application process's memory, do
not store sensitive information, such as credit card numbers or
passwords, in the cache.
And now, at last, you are ready to write code that uses the
Caching block.
Initializing the Caching Block
When you create a project that uses the Caching block, you must
edit the project and code to add references to the appropriate
Enterprise Library assemblies and namespaces.
The assemblies you must add to your project
are:
-
Microsoft.Practices.EnterpriseLibrary.Caching.dll
-
Microsoft.Practices.EnterpriseLibrary.Caching.Cryptography.dll
-
Microsoft.Practices.EnterpriseLibrary.Caching.Database.dll
-
Microsoft.Practices.EnterpriseLibrary.Data.dll
-
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.dll
Note
If you do not wish to cache items in a database, you
don't need to add the Database and Data assemblies. If you do not
wish to encrypt cached items, you don't need to add the two
Cryptography assemblies.
To make it easier to use the objects in the Caching block, you
can add references to the relevant namespaces to your project. Then
you are ready to write some code.