The brilliance of abstracting out implementations from built in framework is sometimes underestimated. In the following example I create my own implementation of ICacheProvider which gives me centralized control as well as the ability to be able to switch in different implementations. So while I am developing (building/rebuilding etc.) I use an implementation that saves the cache to disk so I don’t need to keep reloading it.
Rather then calling to ICacheProvider directly, i.e.:
cache = _cacheProvider.GetCachedItem(key);
we should create our own: (only partial showing)
public interface ICacher where T : class
{
IEnumerable GetFromCache(Cacher.MethodForCache item, stringkey,
intminutesToCache = 30);
}
public classCacher : ICacher where T : class
{
private readonly ICacheProvider<IEnumerable> _cacheProvider;
public delegate IEnumerable MethodForCache(boolfuture = false);
public Cacher(ICacheProvider<IEnumerable> cacheProvider){
_cacheProvider = cacheProvider;
}
public IEnumerable GetFromCache(MethodForCache item,stringkey,
intminutesToCache = -1){
IEnumerable cache = null;
if(_configurationSettings.UseServiceCache){
cache = _cacheProvider.GetCachedItem(key);
}
if(cache == null){cache = item.Invoke();
_cacheProvider.AddCachedItem(cache, key, minutesToCache);
}
return cache;
}
}
And then access like this (with or without delegates):
var someStuff = _cacher.GetFromCache(
delegate
{
return DoSomeStuffForCache(0, true, filter);
},
CacheKeys.DoSomeStuffKey,
_configurationSettings.DoSomeStuffCacheTime);
When we require cache to disk just switch it in: (this example uses Autofac and swaps in when in debug mode)
#if DEBUG
var core = typeof(CacheOnDisk<>).Assembly;
CommonPreStart.RegisterGenericTypes(builder, core,
typeof(ICacheProvider<>), true)
.ForEach(_ => _.InstancePerHttpRequest());
#endif
Click here for the CacheOnDisk implementation:
I also use this for other things, for example a SMS provider with an implementation that sends to text file.