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.