Fix Custom Cache after Sitecore upgrade

Sitecore allows you to create custom caches which can be managed just like all other Sitecore caches. Brian Caos wrote a great blog post about this which can be found here. Recently Sitecore has made some changes to this and if you are upgrading Sitecore you will notice that the code will not compile anymore. For example below code:

 Cache cache = CacheManager.FindCacheByName(cacheName);

will now throw a compile error:

Error CS0411 The type arguments for method 'CacheManager.FindCacheByName<T>(string)' cannot be inferred from the usage. Try specifying the type arguments explicitly. 

Furthermore this now returns an object of type Sitecore.Caching.Generics.ICache<TKey>. My first attempt at fixing this was by just passing the type of my custom cache in the generic which fixes the compile error but now the code throws an exception at runtime:

Exception: System.InvalidCastException 
Message: Unable to cast object of type 'Sitecore.Caching.Cache' to type 'Sitecore.Caching.Generics.ICache`1[MyCustomCache]'.
Source: Sitecore.Kernel
   at Sitecore.Caching.DefaultCacheManager.FindCacheByName[TKey](String name)

The generic now needs the type of the key passed in. In most cases this can just be set to string. To fix this code changes will be required in 2 places.

1. Custom cache object

In the custom cache make sure the base object uses Sitecore.Caching.Generics and also specify string as the key e.g:

 //updated from Sitecore.Caching
using Sitecore.Caching.Generics;

//Specify the generic type of the key
public class MyCustomCache : CustomCache<string> 

2. Custom Cache Clearer

In the method which clears the cache make sure to also pass the same generic for the key, see highlighted line:

private void DoClear()
{
    foreach (string cacheName in Caches)
    {
        //update to pass generic
        Cache cache = CacheManager.FindCacheByName<string>(cacheName); 
        if (cache == null)
            continue;
        Log.Info(this + ". Clearing " + cache.Count + " items from " + cacheName, this);
        cache.Clear();
    }
}