Share via


A Thread Safe Singleton Cache Helper Class

Introduction

Here is my take on the implementation of a cache helper class.

This can be used anywhere, but was developed to be used in BizTalk, in response to a direct, specific request from a client.

I would be *very* attentive to performance when using it with BizTalk. That being said, I believe it turned out nice and clean, and if used in scenarios that make sense, it can make things a lot easier and provide great performance.

Source Code

using System;
using System.Configuration;
using System.Runtime.Caching;
  
namespace Client.Project.HelperClasses
{
  
    /// <summary>
    /// Thread Safe Singleton Cache Class
    /// </summary>
    public sealed  class Cache
    {
        private static  volatile Cache instance; //  Locks var until assignment is complete for double safety
        private static  MemoryCache memoryCache;
        private static  object syncRoot = new Object();
        private static  string settingMemoryCacheName;
        private static  double settingCacheExpirationTimeInMinutes;
        private Cache() { }
  
        /// <summary>
        /// Singleton Cache Instance
        /// </summary>
        public static  Cache Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            InitializeInstance();
  
                        }
                    }
                }
                return instance;
            }
        }
  
        private static  void InitializeInstance()
        {
            var appSettings = ConfigurationManager.AppSettings;
            settingMemoryCacheName = appSettings["MemoryCacheName"];
            if (settingMemoryCacheName == null) 
                throw new  Exception("Please enter a name for the cache in app.config, under 'MemoryCacheName'");
  
            if (! Double.TryParse(appSettings["CacheExpirationTimeInMinutes"], out  settingCacheExpirationTimeInMinutes))
                throw new  Exception("Please enter how many minutes the cache should be kept in app.config, under 'CacheExpirationTimeInMinutes'");
  
            instance = new  Cache();
            memoryCache = new  MemoryCache(settingMemoryCacheName);
        }
  
        /// <summary>
        /// Writes Key Value Pair to Cache
        /// </summary>
        /// <param name="Key">Key to associate Value with in Cache</param>
        /// <param name="Value">Value to be stored in Cache associated with Key</param>
        public void  Write(string  Key, object  Value)
        {
            memoryCache.Add(Key, Value, DateTimeOffset.Now.AddMinutes(settingCacheExpirationTimeInMinutes));
        }
  
        /// <summary>
        /// Returns Value stored in Cache
        /// </summary>
        /// <param name="Key"></param>
        /// <returns>Value stored in cache</returns>
        public object  Read(string  Key)
        {
            return memoryCache.Get(Key);
        }
  
        /// <summary>
        /// Returns Value stored in Cache, null if non existent
        /// </summary>
        /// <param name="Key"></param>
        /// <returns>Value stored in cache</returns>
        public object  TryRead(string  Key)
        {
            try
            {
                return memoryCache.Get(Key);
            }
            catch (Exception)
            {
                return null;
            }
  
        }
  
    }
  
}

See Also

Another important place to find a huge amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki.