Enterprise Library – Cache and Configuration Application Blocks – Patterns and Practices

I tossed up a quick example of using the Enterprise Library Configuration Application Block in your applications, and thought I would give an example of using the Cache Application Block as well.  In this case, I am actually using the two application blocks together so we can seem them side-by-side.  As always, the code will run in Snippet Compiler, but you need to download and install the Enterprise Library and move over the appropriate DLL’s shown in the directory.


In this example, I am using the XML File Storage Provider to save my configuration settings in my sitesettings.config file and using the default storage provider for caching, called the NullBackingStore, which stores the cache information into a Hashtable in memory.


This time when I run the Enterprise Library Configuration tool I need to add both the Caching Application Block and Configuration Application Block to my application (shown below).  I keep the default settings, but I do have to specify that sitesettings.config will be the XML file to store my global application settings.  If you don’t do this, the application will toss an error reminding you to do so.


At first I was a bit confused as to why there is an XML File Storage Provider and XML Serializer Transformer under cachingConfiguration.  I didn’t add it.  It turns out that there is a separate XML file, called by default cachingConfiguration.config, created to store the caching configuration information.  It specifies that I am using the NullBackingStore as well as a few other settings.


 



 


Here is the code that reads and writes to both the configuration file and cache for testing:


 


Testing Application Blocks
using System;
using Microsoft.Practices.EnterpriseLibrary.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Caching;

public class SiteSettings
{
#region Private Members

private string _name;
private string _url;
private string _emailAddress;

#endregion

#region Properties

public string Name
{
get { return _name; }
set { _name = value; }
}

public string Url
{
get { return _url; }
set { _url = value; }
}

public string EmailAddress
{
get { return _emailAddress; }
set { _emailAddress = value; }
}

#endregion
}

public class TestClass
{
public static void Main()
{
// Create initial “siteSettings” object
SiteSettings siteSettings = new SiteSettings();

siteSettings.Name = DavidHayden.com;
siteSettings.Url
= http://www.davidhayden.com/;
siteSettings.EmailAddress
= nospam@nospam.com;

// Save “siteSettings” to the XML config file
ConfigurationManager.WriteConfiguration(SiteSettings, siteSettings);

// Retrieve settings from the XML config file
SiteSettings mySettings = ConfigurationManager.GetConfiguration(SiteSettings) as SiteSettings;

if (mySettings != null)
{
Console.WriteLine(
Name = {0}, mySettings.Name);
Console.WriteLine(
Url = {0}, mySettings.Url);
Console.WriteLine(
Email Address = {0}, mySettings.EmailAddress);
Console.ReadLine();
}

// Get the CacheManager
CacheManager myCacheManager = CacheFactory.GetCacheManager();

// Save the settings to the Cache
myCacheManager.Add(SiteSettings,mySettings);

// Retrieve settings from the cache
SiteSettings cachedSettings = (SiteSettings)myCacheManager.GetData(SiteSettings);

if (cachedSettings != null)
{
Console.WriteLine(
Name = {0}, cachedSettings.Name);
Console.WriteLine(
Url = {0}, cachedSettings.Url);
Console.WriteLine(
Email Address = {0}, cachedSettings.EmailAddress);
Console.ReadLine();
}
}
}


 


Although the configuration settings might be a bit ugly in the backend, the code is pretty straight forward.  I have added comments above so you can see what is happening.  Here are the configuration files:


 


cachetest.exe.config
<configuration>
<configSections>
<section name=enterpriselibrary.configurationSettings
type
=Microsoft.Practices.EnterpriseLibrary.Configuration.
ConfigurationManagerSectionHandler,
Microsoft.Practices.EnterpriseLibrary.Configuration,
Version
=1.0.0.0, Culture=neutral, PublicKeyToken=null />
</configSections>
<enterpriselibrary.configurationSettings
xmlns:xsd
=http://www.w3.org/2001/XMLSchema
xmlns:xsi
=http://www.w3.org/2001/XMLSchema-instance
applicationName
=EntLibTest
xmlns
=http://www.microsoft.com/practices/enterpriselibrary/08-31-2004/configuration>
<configurationSections>
<configurationSection xsi:type=ReadOnlyConfigurationSectionData
name
=cachingConfiguration encrypt=false>
<storageProvider xsi:type=XmlFileStorageProviderData
name
=XML File Storage Provider path=cachingConfiguration.config />
<dataTransformer xsi:type=XmlSerializerTransformerData
name
=Xml Serializer Transformer>
<includeTypes />
</dataTransformer>
</configurationSection>
<configurationSection name=SiteSettings encrypt=false>
<storageProvider xsi:type=XmlFileStorageProviderData
name
=XML File Storage Provider path=sitesettings.config />
<dataTransformer xsi:type=XmlSerializerTransformerData
name
=Xml Serializer Transformer>
<includeTypes />
</dataTransformer>
</configurationSection>
</configurationSections>
<keyAlgorithmStorageProvider xsi:nil=true />
<includeTypes />
</enterpriselibrary.configurationSettings>
</configuration>

 


cacheConfiguration.config
<?xml version=1.0 encoding=utf-8?>
<cachingConfiguration>
<xmlSerializerSection type=Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings,
Microsoft.Practices.EnterpriseLibrary.Caching, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null>
<enterpriseLibrary.cacheSettings xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:xsi
=http://www.w3.org/2001/XMLSchema-instance defaultCacheManager=Cache Manager
xmlns
=http://www.microsoft.com/practices/enterpriselibrary/08-31-2004/cache>
<cacheManagers>
<cacheManager name=Cache Manager expirationPollFrequencyInSeconds=60
maximumElementsInCacheBeforeScavenging
=1000 numberToRemoveWhenScavenging=10>
<cacheStorage xsi:type=CustomCacheStorageData name=Null Storage
type
=Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore,
Microsoft.Practices.EnterpriseLibrary.Caching, Version=1.0.0.0, Culture=neutral,
PublicKeyToken
=null>
<extensions />
</cacheStorage>
</cacheManager>
</cacheManagers>
</enterpriseLibrary.cacheSettings>
</xmlSerializerSection>
</cachingConfiguration>

 


 


sitesettings.config
<?xml version=1.0 encoding=utf-8?>
<SiteSettings>
<xmlSerializerSection type=SiteSettings, cachetest, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null>
<SiteSettings xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:xsi
=http://www.w3.org/2001/XMLSchema-instance>
<Name>DavidHayden.com</Name>
<Url>http://www.davidhayden.com/</Url>
<EmailAddress>nospam@nospam.com</EmailAddress>
</SiteSettings>
</xmlSerializerSection>
</SiteSettings>

 


As you can see, there is certainly a lot of flexiblity with the Enterprise Library as literally you could change the configuration in the backend to specify different storage providers and theoretically never change a single line of code.  There has got to be some price to this flexiblity, which is a couple of XML files to specify settings.  It looks a bit daunting at first if you aren’t used to XML and the plug-in type architecture, but by playing with it more and more one can get comfortable with it pretty quickly.

This entry was posted in Application Blocks. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

7 Responses to Enterprise Library – Cache and Configuration Application Blocks – Patterns and Practices

  1. Sherri Scalish says:

    David:

    Thanks for your response, I already was using the reference to the CacheManager as a local variable so no savings there, but I found an example somewhere where they were using a Delegate to force it on another thread, which works brilliantly for me. The client form is up and visible to them before they ever notice a delay.

    I do have one other problem that perhaps you can help with. The application is using IsolatedStorage by the way, and I have the CacheItemPriority set to Never because we are controlling based on external values. I need to create an Install program (and uninstall) for it, and I see that the files that are in the Documents and Settings\username\Local Settings\Isolated Storage are cryptic at best. As I don’t want this data hanging out there if our application is uninstalled. How would you recommend doing this?

    Thanks in advance

  2. David Hayden says:

    Sherri,

    It would be interesting to know what kind of delays you are experiencing as well as which storage provider you are using for caching.

    I haven’t dug into the code completely, but the CreateCacheManager() method has to go out to the caching configuration file and grab the appropriate cache manager of the default storage provider so it can then create an instance of it using reflection before passing it back to you. The flexibility and extensibility comes with a bit of overhead.

    Aside from doing a little hacking to Enterprise Library or side-stepping it a bit to instantiate the storage provider directly without using reflection, etc., your best defense is to hold onto that instance of the cache manager as long as possible before having to call CreateCacheManager() again. This means making it a member variable of a class and reusing it among all methods as well as passing the instance from class to class as needed.

    In the near future I will play with it some more and see if I can find a better answer to your question.

  3. David Hayden says:

    Brian,

    I can answer your question right here actually.

    Web.Config is absolutely fine for those settings, like your database connection string, that are mainly set once and will essentially never change. However, for those settings that could or may change often, you wouldn’t want those settings in the web.config as any changes made to the web.config restart the application.

    The configuration application block is mainly for settings that are more volatile – could change often. Settings like these should be placed somewhere other than the web.config file, such as in a database or xml file.

    The nice thing about the configuration application block is that it gives you a consistent API no matter if you want to store the settings in an XML file, a database, etc. Therefore, if you initially think an XML file on the web server is adequate but then realize you need to move the settings to the database, you can do this without changing the client code. All you have to do is change the underlying configuration file.

    Certainly keep using the web.config file if it meets your needs as definitely the configuration application block is way overkill and unnecessary in your situation. If your needs change and you need more read/write privileges to those settings, the configuration application block is a good option.

    I hope this helps.

  4. Brian Su says:

    Email me when you have a chance – Brian.Su@m-qube.com

  5. Brian Su says:

    David,

    I tried to use "Configuration Application Block" but I feel it is too complicate to use.

    What do you think if we just use something like this:

    strConn = ((System.Collections.Specialized.NameValueCollection)System.Configuration.ConfigurationSettings.GetConfig("Catalogue"))["DBConn"];

    to retrieve the values from Web.Config? What are the advantages and weaknesses?

    Please help me. Right now my knowledge is too limited.

    Thanks.

    Brian

  6. ShodeN says:

    who need in following too easy example? In real life we need store areas of data (like class with ArayLists of other classes inside)

    If you can please write complex example.

    shoden@rambler.ru

  7. Sherri Scalish says:

    I am wondering if there is any way to speed up the GetCachManager call. It seems this is very slow. My email is (remove JUNK) JUNKsls@seritis.com. Thanks in advance. I thoroughly enjoyed your example by the way.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>