How do you create a CacheManager without setting up the configuration file?

Topics: Caching Application Block
Jun 8, 2007 at 8:31 PM
I'm trying to write defensive code so that if my application's configuration file doesn't have any of the caching information in it, that I can still create a CacheManager with default settings. So far I haven't been able to figure out how to do this. If I get an exception with when calling
CacheFactory.GetCacheManager("cache name");
I could drop back to:
CacheFactory.GetCacheManager();
but that would always give me the same CacheManager back and I'm planning on having a small number of CacheManager for caching specific things. If I used the same strategy everywhere then ALL my CacheManagers would be the same instance. This, of course, is not acceptable.

Specifically what I want to do check to see if a specifically named CacheManager has been configured. If it hasn't then allow me, through code, to add the setup information for that "new" named CacheManager. I could then call CacheFactory.GetCacheManager("cache name") and be sure that it would actually work.
Jun 9, 2007 at 3:01 PM
Are you sure it is worth the effort? If the configuration file doesn't have the cache settings, this would make me wonder what else is wrong with the configuration file. I think a valid configuration file would be part of the application requirements and not having one would just cause an application error that would be logged and bring up an appropriate error message.

Programmatically manipulating cache is tricky as you have to build scavenger policies, backing stores, etc. in a certain order to get the cachemanager configured correctly. Unfortunately, there is no QuickStart on this and I don't know of any examples on the web.

Is this for persistent or memory caching? In general, the block is mainly used for persistent caching. If you are looking for caching in memory, it is recommended that you use System.Web.Caching because it is more rich in functionality.

Regards,

Dave

_____________________________________

David Hayden
Microsoft MVP C#
Jun 11, 2007 at 8:01 AM
Hi Jeff,

I have some code that does most of this - you will just want to keep around a reference to you DictionaryConfigurationSource (see below) - :)

To be clear, I wanted a default cache configuration b/c we were storing all of our configuration in different databases (1 system database and then several hundred application databases), and I couldn't be certain I would have access to the system datdabase when I began "needing" the cache, so I spin up my own configuration source and cache manager.

First here is the code to do it:

internal static DictionaryConfigurationSource GetCachingConfiguration(string policyName) {
DictionaryConfigurationSource configurationSource = new DictionaryConfigurationSource();
CacheManagerSettings cachingConfiguration = new CacheManagerSettings();
cachingConfiguration.DefaultCacheManager = policyName;
Type nullBackingStoreType = Type.GetType(new NullBackingStore().GetType().AssemblyQualifiedName);
CacheStorageData cacheStorageData = new CacheStorageData(CACHESTORAGENAME, nullBackingStoreType);
cachingConfiguration.BackingStores.Add(cacheStorageData);
CacheManagerData cacheManagerData =
new CacheManagerData(policyName, //sent in - whatever you need it to be
EXPIRATIONPOLLFREQUENCYINSECONDS, //60
MAXIMUMELEMENTSINCACHEBEFORE_SCAVENGING, //100
NUMBERTOREMOVEWHENSCAVENGING, //10
CACHESTORAGENAME); //"Null Storage" - You will probably want to send this in as I only wanted 1 default cache
cachingConfiguration.CacheManagers.Add(cacheManagerData);
configurationSource.Add(CACHINGSECTIONNAME, cachingConfiguration);
return configurationSource;
}

I have included the above code in a class file called DefaultConfiguration.cs - be a little forewarned - when you start introducing other configurations and the dependencies between configurations increase, it gets interesting pretty quick.

That being said, the calling code of the above looks like this:

DictionaryConfigurationSource configurationSource = DefaultConfiguration.GetCachingConfiguration(policyName);
CacheManagerFactory factory = new CacheManagerFactory(configurationSource);
cacheManager = factory.Create(policyName);

I hope this helps you.

Regards,
Chris

Jun 12, 2007 at 5:50 PM
The application I'm working on doesn't use the application's configuration file. Instead, a simple configuration system was written in the application. This is partially a "not built here" and partially to do things like they were done in the original application. I'm not sure I want to fight the battle to use over what is "right".

In any case, there should be a simple way to dynamically create a cache. I can imagine an application where I don't know how many cache's I need. For example one per web site, etc.

I intend to use this only for an in memory cache but am in a WinForms application so can't use System.Web.Caching. At least the documentation says you shouldn't use it. Has this changed?
Jun 12, 2007 at 5:54 PM
Your code was exactly what I needed. Thanks!

BTW, the code:
Type.GetType(new NullBackingStore().GetType().AssemblyQualifiedName);
should be replaced with:
typeof(NullBackingStore);
You are actually creating an instance just so you can call GetType on it.

It looks like the line:
configurationSource.Add(CACHINGSECTIONNAME, cachingConfiguration);
has to be:
configurationSource.Add("cachingConfiguration", cachingConfiguration);
At least that what I needed to get it to work.

Thanks again. That was exactly what I needed!
Jun 12, 2007 at 6:29 PM
Jeff,

Glad to help - good call on the NullBackingStore().GetType(). The CACHINGSECTIONNAME was a constant for me, so you are correct in changing it to whatever you like.

Good luck.

Chris
Dec 26, 2008 at 3:09 PM
Chris,

I tried the solution you have suggested, but it looks like I am doing something wrong as its not working the way I wanted.

e.g. I added the custom configuration class and created a factory, but If I add it this way, if I try to get the manager back using the name, it returns me null.

Following is sample code I am trying to

code in button1 handler
 DictionaryConfigurationSource configurationSource = CacheConfigurationFactory.GetCachingConfiguration("Test",30,0,10); // I provided caching parameters in my GetCacheConfiguration method.
            CacheManagerFactory factory = new CacheManagerFactory(configurationSource);
            CacheManager cm = factory.Create("Test");
            cm.Add("test", "test");

 code in button2 handler
CacheManager cm = CacheFactory.GetCacheManager("Test");
            string test = cm.GetData("test") as string;

the button2 handler code should return be the same object as in the button 1, but it doesn't.

could you please let me know if this is how it should be working or I am doing something wrong...

Please advise...


Dec 28, 2008 at 8:33 AM
As mentioned above, you should keep a reference of the dictionaryconfigurationsource.  You should create the CacheManager from a CacheManagerFactory which uses that configuration source in the button2 handler as well.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 27, 2009 at 5:41 PM
Hi Sarah,

I tried it and its not working for me..

following is the code snippet...

can u please suggest whats wrong?

====

 

DictionaryConfigurationSource configurationSource; //SHARED CONFIG SOURCE

 

 

private void AutoConfigTestButton_Click(object sender, EventArgs e)

 

{

configurationSource =

CacheConfigurationFactory.GetCachingConfiguration("Test");

 

 

CacheManagerFactory factory = new CacheManagerFactory(configurationSource);

 

 

CacheManager cm = factory.Create("Test");

 

cm.Add(

"test", "test");

 

 

string test = cm.GetData("test") as string;//ADDING ITEM TO CACHE

 

}

 

private void AutoConfigGetButtonTest_Click(object sender, EventArgs e)

 

{

 

CacheManagerFactory factory = new CacheManagerFactory(configurationSource);

 

 

CacheManager cm = factory.Create("Test");

 

 

string test = cm.GetData("test") as string; //THIS IS RETURNING NULL

 

}

Jan 28, 2009 at 9:36 AM
Hi,

I think you should also keep a reference to the instance of CacheManager because there you will poll the cached data. I tried the code snippets and i got it to work. I tried this in a Winforms app.

Here:

        private IConfigurationSource DictionaryConfigSource

        {

            get;

            set;

        }

 

        private ICacheManager CacheManager

        {

            get;

            set;

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

 

        }

 

        private void DoGet_Click(object sender, EventArgs e)

        {

            string test = this.CacheManager.GetData("test") as string;

        }

 

        private void DoCreate_Click(object sender, EventArgs e)

        {

            this.DictionaryConfigSource = GetCachingConfiguration("test");

            CacheManagerFactory factory = new CacheManagerFactory(this.DictionaryConfigSource);

            this.CacheManager = factory.Create("test");

            this.CacheManager.Add("test", "Something from the Cache");

        }

 

        internal static DictionaryConfigurationSource GetCachingConfiguration(string policyName)

        {

            DictionaryConfigurationSource configurationSource = new DictionaryConfigurationSource();

            CacheManagerSettings cachingConfiguration = new CacheManagerSettings();

            cachingConfiguration.DefaultCacheManager = policyName;

            Type nullBackingStoreType = Type.GetType(new NullBackingStore().GetType().AssemblyQualifiedName);

            CacheStorageData cacheStorageData = new CacheStorageData("MyCACHE", nullBackingStoreType);

            cachingConfiguration.BackingStores.Add(cacheStorageData);

            CacheManagerData cacheManagerData =

            new CacheManagerData(policyName, 60, 100, 10, "MyCACHE");

            cachingConfiguration.CacheManagers.Add(cacheManagerData);

            configurationSource.Add(CacheManagerSettings.SectionName, cachingConfiguration);

            return configurationSource;

        }


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com