Simple generic C# caching class (I use this all the time)

I wanted to add this simple class that I find myself using all the time in every project that I create. It is a generic caching class:

CacheProvider`1.cs

    public abstract class CacheProvider<TCache> : ICacheProvider
    {

        public int CacheDuration
        {
            get;
            set;
        }

        private readonly int defaultCacheDurationInMinutes = 30;

        protected TCache _cache;

        public CacheProvider()
        {
            CacheDuration = defaultCacheDurationInMinutes;
            _cache = InitCache();
        }
        public CacheProvider(int durationInMinutes) 
        {
            CacheDuration = durationInMinutes;
            _cache = InitCache();
        }

        protected abstract TCache InitCache();

        public abstract bool Get<T>(string key, out T value);

        public abstract void Set<T>(string key, T value);

        public abstract void Set<T>(string key, T value, int duration);

        public abstract void Clear(string key);

        public abstract IEnumerable<KeyValuePair<string, object>> GetAll();

    }

ICacheProvider.cs

    public interface ICacheProvider
    {
        /// <summary>
        /// Retrieve cached item
        /// </summary>
        /// <typeparam name="T">Type of cached item</typeparam>
        /// <param name="key">Name of cached item</param>
        /// <param name="value">Cached value. Default(T) if
        /// item doesn't exist.</param>
        /// <returns>Cached item as type</returns>
        bool Get<T>(string key, out T value);

        /// <summary>
        /// Insert value into the cache using
        /// appropriate name/value pairs
        /// </summary>
        /// <typeparam name="T">Type of cached item</typeparam>
        /// <param name="value">Item to be cached</param>
        /// <param name="key">Name of item</param>
        void Set<T>(string key, T value);

        /// <summary>
        /// Insert value into the cache using
        /// appropriate name/value pairs WITH a cache duration set in minutes
        /// </summary>
        /// <typeparam name="T">Type of cached item</typeparam>
        /// <param name="key">Item to be cached</param>
        /// <param name="value">Name of item</param>
        /// <param name="duration">Cache duration in minutes</param>
        void Set<T>(string key, T value, int duration);

        /// <summary>
        /// Remove item from cache
        /// </summary>
        /// <param name="key">Name of cached item</param>        
        void Clear(string key);

        IEnumerable<KeyValuePair<string, object>> GetAll();

    }

I tend to use dependency injection to implement this cache. Here is a concrete implementation of my cache provider:

    public class HttpCache : CacheProvider<Cache>
    {
        protected override Cache InitCache()
        {
            return HttpRuntime.Cache;
        }

        public override bool Get<T>(string key, out T value)
        {
            try
            {
                if (_cache[key] == null)
                {
                    value = default(T);
                    return false;
                }

                value = (T)_cache[key];
            }
            catch
            {
                value = default(T);
                return false;
            }

            return true;
        }

        public override void Set<T>(string key, T value)
        {
            Set<T>(key, value, CacheDuration);
        }

        public override void Set<T>(string key, T value, int duration)
        {
            _cache.Insert(
                key,
                value,
                null,
                DateTime.Now.AddMinutes(duration),
                TimeSpan.Zero);
        }

        public override void Clear(string key)
        {
            _cache.Remove(key);
        }

        public override IEnumerable<KeyValuePair<string, object>> GetAll()
        {

            foreach (DictionaryEntry item in _cache)
            {
                yield return new KeyValuePair<string, object>(item.Key as string, item.Value);
            }

        }
    }

View the source on GitHub: Omegaluz.Caching

Update, here is a new article with an example: Using the C# generic cache: the Tester Doer pattern

7 thoughts on “Simple generic C# caching class (I use this all the time)

  1. looks similar to mine, but I dont see a cache invalidate function. sometimes I need to invalidate the cache, but I wont rebuild it unless a client request it. The data that gets cached could have multiple changes before the next request. Also you could pass in a function that rebuilds the cache so when the cache automatically invalidates it has option to rebuild based on that action.

    • Thanks for the feedback. I’ve never had a use for that functionality. Can you describe a specific use case. I’d love to see how you’ve implemented that.

  2. Pingback: Using the C# generic cache: the Tester Doer pattern ← Code is Hard

  3. This is great but not threadsafe. Consider reader/writer locks on your Insert and Remove. Also the GetAll throws a casting error b/t the DE and KVP objects.

Leave a Reply