Skip to content

Instantly share code, notes, and snippets.

@kcargile
Created August 7, 2012 16:54
Show Gist options
  • Save kcargile/3287276 to your computer and use it in GitHub Desktop.
Save kcargile/3287276 to your computer and use it in GitHub Desktop.
.NET templated base class that provides a caching method that will query automatically in the case of a cache miss using a function pointer.
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Caching
{
public abstract class CachedServiceBase<T> where T : class
{
private static readonly object Lock = new object();
protected ICacheProvider<T> Cache;
public abstract List<T> Get();
protected CachedServiceBase(ICacheProvider<T> cacheProvider)
{
if (null == cacheProvider)
{
throw new ArgumentNullException("cacheProvider");
}
}
protected virtual T TryGetFromCacheAddIfMissing(MethodBase callingMethod, Func<T> query, params object[] keyHints)
{
if (null == callingMethod)
{
throw new ArgumentNullException("callingMethod");
}
if (null == query)
{
throw new ArgumentNullException("query");
}
string cacheKey = BuildCacheKey(callingMethod, keyHints);
T maybeFromCache = Cache.Get(cacheKey);
if (null != maybeFromCache)
{
return maybeFromCache;
}
lock (Lock)
{
maybeFromCache = Cache.Get(cacheKey);
if (null != maybeFromCache)
{
return maybeFromCache;
}
maybeFromCache = query.Invoke();
if (null != maybeFromCache)
{
Cache.Insert(cacheKey, maybeFromCache);
}
}
return maybeFromCache;
}
protected virtual string BuildCacheKey(MethodBase methodInfo, params object[] keyHints)
{
if (null == methodInfo)
{
throw new ArgumentNullException("methodInfo");
}
return string.Format("{0}::{1}", GetType().FullName, methodInfo.Name);
}
}
}
namespace Caching
{
public interface ICacheProvider<T> where T : class
{
T Get(string cacheKey);
void Insert(string cacheKey, T objectToCache);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment