The following code shows an example of implementing the Microsoft AppFabric Caching mechanism (part of the Azure framework). I wanted a generic caching helper which can be used by calling code without too much effort or consideration for the internal workings, such as how data from different sources is partitioned (to avoid ID conflicts). The way I have done this is to the fully qualified type name, supplied by the generic parameter. In the event that the AppFabric server could not be contacted on startup, there is an alternative memory based cache, which allows the programmer to specify names of types which should not be included in the memory based cache.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.ApplicationServer.Caching;
using System.Text.RegularExpressions;

namespace Common.FabricCache
{
    public static class FabricCacheHelper
    {

        public static object SyncLock = new object();
        static DataCacheFactory myCacheFactory;
        static DataCache myFabricCache;

        static FabricCacheHelper()
        {
            PrepareClient();
        }

        public static T GetFromCache<T>(string key)
        {
            if (myFabricCache != null)
            {
                //user the region per type and use the key as the identifier within that region
                return (T)myFabricCache.Get(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
            }
            else
            {
                return (T)AlternateCache.Get(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
            }
        }

        public static void AddToCache<T>(string key, T value)
        {
            if (value != null)
            {
                if (myFabricCache != null)
                {
                    //create a region per type and use the key as the identifier within that region
                    myFabricCache.CreateRegion(Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                    myFabricCache.Put(key, value, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                }
                else
                {
                    //create a region per type and use the key as the identifier within that region
                    AlternateCache.CreateRegion(Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                    AlternateCache.Put(key, value, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                }
            }
        }

        public static void RemoveFromCache<T>(string key)
        {
            if (myFabricCache != null)
            {
                myFabricCache.Remove(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
            }
            else
            {
                AlternateCache.Remove(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
            }
        }

        private static void PrepareClient()
        {
            //-------------------------
            // Configure Cache Client 
            //-------------------------

            //Define Array for 1 Cache Host
            List<DataCacheServerEndpoint> servers = new List<DataCacheServerEndpoint>(1);

            //Specify Cache Host Details 
            //  Parameter 1 = host name
            //  Parameter 2 = cache port number
            string fabricHost = System.Configuration.ConfigurationManager.AppSettings["FabricHost"];// = "localhost";
            int fabricPort = int.Parse(System.Configuration.ConfigurationManager.AppSettings["FabricPort"]); // 22233;
            servers.Add(new DataCacheServerEndpoint(fabricHost, fabricPort));

            //Create cache configuration
            DataCacheFactoryConfiguration configuration = new DataCacheFactoryConfiguration();

            //Set the cache host(s)
            configuration.Servers = servers;

            //Set default properties for local cache (local cache disabled)
            configuration.LocalCacheProperties = new DataCacheLocalCacheProperties();

            //Disable exception messages since this sample works on a cache aside
            DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);

            //Pass configuration settings to cacheFactory constructor
            myCacheFactory = new DataCacheFactory(configuration);

            //Get reference to named cache
            try
            {
                string fabricCacheName = System.Configuration.ConfigurationManager.AppSettings["FabricCacheName"];
                myFabricCache = myCacheFactory.GetCache(string.IsNullOrEmpty(fabricCacheName) ?  "myFabricCache" : fabricCacheName);
            }
            catch (Exception)
            {
                //if anything goes wrong with the fabric, just carry on which will use the alternate method
                myFabricCache = null;
            }
        }

        #region "Alternative Cache - Memory Based"
        private static class AlternateCache
        {
            private static Dictionary<string, Dictionary<string, object>> _alternateMemoryCache = new Dictionary<string, Dictionary<string, object>>();

            //some types are known to be large, so we wouldnt want them in the w3wp process memory of this alternative cache - they should be ignored (as if not cached)
            private static string[] _typeNameRegionRestrictions = new string[]
            {
            };

            internal static object Get(string key, string region)
            {
                Dictionary<string, object> regionCache;
                
                if (_alternateMemoryCache.TryGetValue(region, out regionCache))
                {
                    object value;
                    if (regionCache.TryGetValue(key, out value))
                    {
                        return value;
                    }
                }

                //wasnt in the cache
                return null;
            }

            internal static void CreateRegion(string region)
            {
                //is this region allowed, or are we blocking this type?
                if (!IsRestrictedRegionName(region))
                {
                    if (!_alternateMemoryCache.ContainsKey(region))
                        _alternateMemoryCache.Add(region, new Dictionary<string, object>());
                }
            }

            internal static void Put(string key, object value, string region)
            {
                Dictionary<string, object> regionCache;
                if (_alternateMemoryCache.TryGetValue(region, out regionCache))
                {
                    if (!regionCache.ContainsKey(key))
                        regionCache.Add(key, value);
                    else
                        regionCache[key] = value;
                }
            }

            internal static void Remove(string key, string region)
            {
                Dictionary<string, object> regionCache;
                if (_alternateMemoryCache.TryGetValue(region, out regionCache))
                {
                    if (regionCache.ContainsKey(key))
                        regionCache.Remove(key);
                }
            }

            private static bool IsRestrictedRegionName(string typeName)
            {
                return _typeNameRegionRestrictions.Contains(typeName);
            }
        }
        #endregion


    }
}