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. akismet-889bf04a613f9c68792075d37a6f356eni

    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.

    Reply
    1. Andy Cohen Post author

      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.

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

  3. Nice Work

    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.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s