Skip to content

Instantly share code, notes, and snippets.

@chrisfcarroll
Last active February 19, 2016 11:02
Show Gist options
  • Save chrisfcarroll/47252612664443a3d347 to your computer and use it in GitHub Desktop.
Save chrisfcarroll/47252612664443a3d347 to your computer and use it in GitHub Desktop.
A simple memoizer backed by System.Runtime.Caching.MemoryCache.Default
using System;
using System.Reflection;
using System.Runtime.Caching;
/// <summary>Memoize the results of method calls.</summary>
class Cacher
{
public readonly string UniqueName;
public readonly int CacheTimeSeconds;
/// <param name="cacheTimeSeconds">Used to set absolute expiry this many seconds in the future</param>
/// <param name="uniqueName">Optional because your methods are usually uniquely identified by AssemblyQualifiedTypeName.MethodName.</param>
public Cacher(int cacheTimeSeconds, string uniqueName="")
{
this.UniqueName = uniqueName;
CacheTimeSeconds = cacheTimeSeconds;
if (CacheTimeSeconds < 1) { CacheTimeSeconds = 1; }
}
public TR Call<TR>(Func<TR> callback) { return FromCacheOrCallback(KeyFor(callback.Method), callback); }
public TR Call<T1, TR>(Func<T1, TR> callback, T1 param)
{
return FromCacheOrCallback(KeyFor(callback.Method, param), () => callback(param));
}
public TR Call<T1, T2, TR>(Func<T1, T2, TR> callback, T1 param, T2 param2)
{
return FromCacheOrCallback(KeyFor(callback.Method, param, param2), () => callback(param, param2));
}
public TR Call<T1, T2, T3, TR>(Func<T1, T2, T3, TR> callback, T1 param, T2 param2, T3 param3)
{
return FromCacheOrCallback(KeyFor(callback.Method, param, param2, param3), () => callback(param, param2, param3));
}
public TR Call<T1, T2, T3, T4, TR>(Func<T1, T2, T3, T4, TR> callback, T1 param, T2 param2, T3 param3, T4 param4)
{
return FromCacheOrCallback(KeyFor(callback.Method, param, param2, param3, param4), () => callback(param, param2, param3, param4));
}
public TR Call<T1, T2, T3, T4, T5, TR>(Func<T1, T2, T3, T4, T5, TR> callback, T1 param, T2 param2, T3 param3, T4 param4, T5 param5)
{
return FromCacheOrCallback(KeyFor(callback.Method, param, param2, param3, param4, param5),
() => callback(param, param2, param3, param4, param5));
}
T FromCacheOrCallback<T>(string keystring, Func<T> callback)
{
var value = MemoryCache.Default.Get(keystring);
if (value == null)
{
value = callback();
MemoryCache.Default.Add(keystring, value, DateTime.Now.AddSeconds(CacheTimeSeconds));
}
return (T) value;
}
string KeyFor(MethodInfo methodInfo, object p1 = null, object p2 = null, object p3 = null,
object p4 = null, object p5 = null, object p6 = null, object p7 = null)
{
var hasType = methodInfo.DeclaringType != null;
var typeAQName = hasType ? methodInfo.DeclaringType.AssemblyQualifiedName : methodInfo.GetHashCode().ToString();
return string.Format("{0}({1}, {2}, {3}, {4}, {5}, {6}, {7}):{8}:{9}",
methodInfo.Name,
p1, p2, p3, p4, p5, p6, p7,
typeAQName,
UniqueName);
}
}
@chrisfcarroll
Copy link
Author

var cacher = new Cacher(20);
var result= cacher.Call( object.Method, param1, param2);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment