Caching by Reference

Topics: Caching Application Block
Dec 10, 2010 at 2:32 PM

Hi

I am using EntLib 4.1 Caching Application block configured to use In-Memory Caching.

After I retrieve a previously cached object from the Cache any changes I make afterwards gets automatically reflected on the Cached object.

So, if I get the object again, its no more the original cached object. Is this the expected behavior? Or am I doing something wrong here?

Is there a way to overcome this behavior?

I need to fix this quickly, May I expect a quick response?


By the way, I am ex-employee of Avanade :)

 

Thanks

Firoz Ozman

www.firozozman.com

Dec 10, 2010 at 3:16 PM

I had a look at the source code and understood that this behavior is by Design.

Thanks everyone for your attention.

My question now is, what if someone want to override this behavior? Do they need to clone the object fetched out of cache?

 

Dec 13, 2010 at 9:24 AM

Hi firozozman,

I haven't yet confirmed the behaviour you mentioned from my end. Though, I'm just curious how are you doing this "After I retrieve a previously cached object from the Cache any changes I make afterwards gets automatically reflected on the Cached object.". If you would want to have a more out-of-the-box behaviour then one approach I can think of is to create a custom cache manager. Kindly see documentation for reference - http://msdn.microsoft.com/en-us/library/cc511539.aspx. Thanks.

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 13, 2010 at 1:18 PM

Hi Gino

Thanks for the quick response.

Here is the code snippet. CacheHelper does the Get and Set Cache on an in-memory cache.

public class CacheHelper
    {
        public  object GetCacheObject(string key)
        {
            object obj = null;
            try
            {
                ICacheManager objectCache = CacheFactory.GetCacheManager();
                obj = objectCache.GetData(key);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("CacheTest", ex.Message);
            }
            return obj;
        }

      public  void SetCacheObject(string key, object value)
        {
            try
            {
                ICacheManager objectCache = CacheFactory.GetCacheManager();


                objectCache.Add(key, value,
                    CacheItemPriority.Normal,
                    null,
                    new SlidingTime(new TimeSpan(0,5,0)));
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("CacheTest", ex.Message);
            }

        }
    }

 

Here is how we use it.

CacheHelper ch = new CacheHelper();
User usernew = new User() { UserName = "InitialValue" };
ch.SetCacheObject("TestUser", usernew);
label1.Text = "1. Initial value: " + usernew.UserName;

User userread = new User();
userread = (User)ch.GetCacheObject("TestUser");
label1.Text = "2. Value fetched from Cache: " + userread.UserName;

User usermodifiy = new User();
usermodifiy = (User)ch.GetCacheObject("TestUser");
usermodifiy.UserName = "TestUserModified";
label1.Text = "3. Modified Value:" + usermodifiy.UserName;

User userread = new User();
userread = (User)ch.GetCacheObject("TestUser");
label1.Text = "4. Value fetched from Cache: " + userread.UserName;

 

Here is the output:

1. Initial value: Initial Value
2. Value fetched from Cache: Initial Value
3. Modified Value: TestUserModified
4. Value fetched from Cache: TestUserModified

I am expecting to get "Initial Value" in step 4 as I did not persist the change on Step 3 back to Cache.

Please comment.

Thanks

Firoz

 

Dec 14, 2010 at 4:58 AM

You're assesment is correct, the change you made gets reflected inside the cache because the Caching Application Block internally uses a hashtable and that's how the hashtable behaves.  The simplest I could think of as a workaround if you don't like that behavior is yes, to have your object implement the ICloneable interface.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 14, 2010 at 1:44 PM

 

Thanks Sarah

We have implemented the workaround :)

Firoz Ozman