Critique: Pluggable ASP.NET CacheManager

Today as I was perusing DotNetKicks I ran across this post by John Sheehan. The post goes over creating a simple CacheManager that allows extensibility through interfaces. The basis of his class is dervived off the usage of.

public class CacheManager
{
    protected ICacheProvider _repository;
    public CacheManager(ICacheProvider repository)
    {
        _repository = repository;
    }

    public void Store(string key, object data)
    {
        _repository.Store(key, data);
    }

    public void Destroy(string key)
    {
        _repository.Destroy(key);
    }

    public T Get<T>(string key)
    {
        return _repository.Get<T>(key);
    }
}

You can view the full source with the implemenation of the interfaces and the declaration of the ICacheProvider interface over at his blog at Pluggable ASP.NET CacheManager.

Reading this post and one of the comments on his blog made me follow up in his comment stream, I felt like posting it here as it may benefit some of you also. Firstly I had to acknowledge the fact that Enterprise Library exists and contains it’s own Caching Application Block. Which also handles the concrete usages of the CacheProvider’s through a Factory implementation on the manager instead of concrete usage of the manager.

One of the posters on his blog asked the question “What’s the point in using CacheManager instead of just using the ICacheProvider instances?” This triggered my response on the elegance of this design John choose to follow for loosely coupling his code rather than direct coupling.

With your question if you implemented the caching solution using only the specific classes if you ever decided you wanted to change your caching backing store from HttpRuntime.Cache (note: John, you should reference the cache as HttpRuntime.Cache instead of Httpcontext.Current.Cache, calling the context just causes extra processing to just resolve to HttpRuntime.Cache) to a sql data store or to a memory caching solution like memcache or velocity you will now have to go into you code and change every single usage of RequestProvider to use MemCacheProvider or whatever other implementation you wish to use.

With a loosely coupled implementation that John created here, if you ever wish to switch from one provider to another you only ever need to change where it instantiates CacheManger to use the new provider instead. This brings me to my point about Enterprise Library’s CacheManager having a factory method for creating the caching providers usage, this will allow you to only need to declare the CacheProviders once in your code and no matter how many times you change the concrete implmentation of ICacheProvider you will only ever need to change 1 line of code in the entirety of your project which is a great thing indeed.

This idea of creating shared services that you can plug and play based off of interfaces is the basis of the idea of “Inversion of Control” or IoC that creates very robust and completely decoupled projects. Some of the most well known IoC frameworks are Microsoft’s Unity, Spring.NET, Castle Windsor, Ninject, StructureMap to name a few there are quite a bit of frameworks out there for IoC. Creating loosely coupled code is definitely getting to the point where it is mandatory for a project to be a well made solution.

It’s always a good day when I have the chance to discuss genericism, interfaces, loose coupling and inversion of control.

BloggingContext.ApplicationInstance.CompleteRequest();