CacheAdapter–Now a Nuget package

Note: Link to Wiki is here

A while ago, I blogged about a personal project around caching that allowed you to abstract away the underlying cache mechanism, and use whatever cache you wanted. 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, or you can use the Windows AppFabric caching to taker advantage of distributed caching.

Well, its now a package on Nuget that you can easily install and use immediately. You can grab it from here.

install-package-image

Update: This package uses the Microsoft Public Licence (MS-PL).

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:

<setting name="CacheToUse" serializeAs="String">
    <value>Memory</value>
</setting>

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

<setting name="CacheToUse" serializeAs="String">
    <value>Web</value>
</setting>

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:

<setting name="CacheToUse" serializeAs="String">
    <value>AppFabric</value>
</setting>

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:

<setting name="DistributedCacheServers" serializeAs="String">
    <value>localhost:22223</value>
</setting>
<setting name="DistributedCacheName" serializeAs="String">
    <value>MyCache</value>
</setting>

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.

So go grab it. Or you can download the source code form here and change it to your hearts content. Its actually a relatively simple implementation and it would be easy to plug in any underlying cache implementation should you wish.

15 Comments

  • Thanks for sharing.

  • I tend to prefer HttpRuntime.Cache over System.Web.HttpContext.Current.Cache. If you’re not in an environment where HttpContext doed not exist it will not throw errors rather return cache misses

  • Why would I want to switch from using the Microsoft recommended Enterprise Library 5.0 Caching Application Block to this new method, losing the synergy of Microsoft Enterprise Library along the way?

  • This looks well done and very useful!

    I'm interested in using your CacheAdapter in my own projects but wonder what is the license?

    It is difficult to use something without an explicit license, hopefully something very permissive like MsPl or Apache or MIT or BSD.

    Could you clarify this? Sorry if you already have this information somewhere and I've missed it.

    Thanks!

  • F.Morrison,

    EntLib caching block is just an option and one you can plug-in to this code base easily. ASP.NET Web cache (IMHO) is far superior to EntLib caching and I dont want to introduce dependecies to Entlib if I dont have to. Switching then to an even more powerful caching mechanism such as AppFabric is just some config changes. No code change but still taking full advantage of distributed cache farms, something Entlib caching cannot do. In addition, Entlib caching utilises a different syntax. This library removes that and provides a thin consistent layer between code and cache.

  • Hi Joe,

    I have updated the post to include the licencing information. It is distributed under the Microsoft Public Licence (MS-PL).

  • i think you should also add Add() or Set() methods in Icacheprovider because some times we only want to add data otherwise we have to fetch data to insert it into cache. I hope u got it what i'm saying.

    btw great work. Keep helping the community.

    Thanks.

  • How hard would it be to convert this into a EF provider?

  • I would imagine quite easy. The code is not very complicated and it is just an interface based approach. It is not something on my horizon tho, but you could fork the codebase and go for it.

  • How to clear cache when using this cache adapter. Thanks

  • One Page Check Out for Virtuemart plugin - no HACK, 100% AJAX, Compatiple with Virtuemart 2.0.x

    All Virtuemart site need One page checkout to make the check out process as simple as possiple while remain the powerfull function your payment and customer information.

  • Seems to be a good idea, but implementation looks incomplete.

    1) Having all cache adapters in 1 assembly resulted in unused references (for example - if I'm using memcached I don;t want to see references to AppFabric)
    2) Implementation of AddToPerRequestCache in AppFabric and Inmemory cache is completely incorrect:
    this.Add(cacheKey, TimeSpan.FromSeconds(1.0), dataToAdd);
    It could be useful to introduce some Scope object to allow using this method for WCF requests for example

  • thiet ke,
    It is currently not possible to clear the entire cache programmatically using this package. Only individual items. Pls add this as a feature request to the BitBucket repo and I'll attempt to get to it.

  • Hi Mikhail,

    Thanks for the comments, in response.
    1. The assembly references are necessary to get it to compile, otherwise I'd have to conditionally remove code and that defeats the whole purpose of then being able to switch providers via config as it would then require re-injection code. overall its a pretty minimal price to pay.

    2. This has been completely re-written in the latest code base. The nuget package has not been updated yet as I am working on some larger scale changes that goes with it.

  • Hi Louis,

    The problem will be related to config, specifically the
    MessageSecurityAuthorizationInfo entry in the CacheSpecificData section. It seems like its not a valid key and might be missing a character or something like that.

    You can contact me on glav AT theglavs.com and I'll be happy to help.

Comments have been disabled for this content.