Clone wiki

CacheAdapter / Home

Cache Adapter

Generic cache mechanism that supports memory, ASP.NET, AppFabric, memecached, or redis cache via config.

Links to blog posts with further details:
Original Post describing the ideas and architecture
Latest post describing changes to project and announcing Nuget package availability

This is a personal project around caching that allows you to abstract away the underlying cache mechanism, and use whatever cache you want. Through simple configuration, you can choose to use either the memory cache provided by System.Runtime.Caching in .Net 4, the traditional ASP.NET web cache, Windows AppFabric caching or the open source memcached engine to take advantage of distributed caching.

Just as a recap, you can use this cache adapter like this:

var data1 = cacheProvider.Get<SomeData>("cache-key", DateTime.Now.AddSeconds(3), () =>
    // This is the anonymous function which gets called if the data is not in the cache.
    // This method is executed and whatever is returned, is added to the cache with the
    // passed in expiry time.
    Console.WriteLine("... => Adding data to the cache... 1st call");
    var someData = new SomeData() { SomeText = "cache example1", SomeNumber = 1 };
    return someData;

(Note: You will get a small example .cs file included in your project that contains this example usage when you install the package)

You can see in the example, that you can request the data, and provide a lambda that retrieves that data if its not in the cache. The data gets added to the cache once the lambda has been executed to retrieve the data from the source. Also, the data that is returned is strongly typed. It is not a generic object that you then need to cast.

Additionally, you can set the type of cache used by one line of configuration:

<add key="CacheToUse" value="Memory" />

If I wanted to use the ASP.NET Web cache, I could simply set the config item like so:

<add key="Web" value="Web" />

And if I wanted to use the AppFabric distributed cache (assuming it has been installed on the system), then I can simply set the config like so:

<add key="CacheToUse" value="AppFabric" />

And to use memcahced:

<add key="CacheToUse" value="memcached" />

And to use Redis:

<add key="CacheToUse" value="redis" />

The package references the required AppFabric client assemblies for you. This means you can write a web application today using this package and use the traditional ASP.NET cache. Then we you are ready, install AppFabric, setup a cache cluster, change the configuration to enable AppFabric and you are away. No code changes to your app.

Using AppFabric

To use AppFabric, there are a few extra things to do by way of Infrastructure. Obviously, you need to download and install it. Then you need to setup your cache cluster via the wizard when you install it (or via powershell if you choose). During this process you will be creating some cache nodes and you need to create a named cache for your application. This can be done via powershell using the

New-Cache {cachename} 

powershell command. In addition, you will need to ensure that the user that will be accessing the cache has access to it. Again, this can be done from powershell via the:

Grant-CacheAllowedClientAccount {account} 

There is some additional config you will need to do as well. In the application config file you will need to change the following entries to match your configured infrastructure:

<add key="DistributedCacheServers"  value="localhost:22223" />
<add key="DistributedCacheName" value="MyCache" />

The “DistributedCacheServers” setting can be a comma separated list of servers and ports that the cache client (ie. your app) will communicate with. This can be one or as many comma separated entries as you like and depends on your cache cluster config.

The “DistributedCacheName” is the name of the cache you have setup in the cache cluster for your app. (Detailed above)

Final Notes

Before I published this package, I cleaned it up a bit as I have been using it on a current project and I didn’t like a number of ways I implemented things initially. Instead of multiple assemblies, everything is in the one assembly.

Also, I removed the use of Unity as a mechanism for dependency injection and implemented a very very simple method which uses no particular dependency injection implementation. I did this because everyone wants to do DI (Dependency Injection) using their favourite implementation whether this be Unity, Autofac, Ninject, Castle Windsor etc. etc. So I opted for something that does the job, it is not what a purist would be happy with, but is dead simple to rip out and change which is what I expect most people would do.

Finally, because all cache access is via an interface, it allows for easy testability.