Кеширование результата исполнения метода в .NET
Иногда бывает необходимо кешировать результат исполнения определённого метода. Удобно, когда можно использовать достаточно универсальный способ, который подошел бы для кеширования результата выполнения произвольного кода с заранее неизвестным типом возвращаемого значения.
Идея была давным-давно где-то подсмотрена, к сожалению оригинала не удалось найти, чтобы поставить на него ссылку.
Первая часть решения. Будем использовать Generic Delegate
namespace CrispStudio.Routine
{
public static class UtilsCache
{
public delegate T MethodExecution<T>();
public static T GetCachedMethod<T>(string cacheKey, DateTime cacheExpiration, CacheDependency cacheDependencies, MethodExecution<T> method)
{
try
{
if (_context.Cache[cacheKey] == null)
{
_context.Cache.Insert(cacheKey,
method(),
cacheDependencies,
cacheExpiration,
Cache.NoSlidingExpiration);
}
return (T)_context.Cache[cacheKey];
}
catch
{
return method();
}
}
}
}
Вся прелесть метода в том, что внутри анонимного делегата с уже определённой сигнатурой можно писать практически любой код, возвращающий объект заранее неизвестного методу кеширования типа.
Пример использования:
var MySlowToConstructObject = UtilsCache.GetCachedMethod(
"KEY_IN_CACHE",
DateTime.Now.AddSeconds(300),
new CacheDependency(HostingEnvironment.MapPath("~/Web.config")),
delegate()
{
/*
Тут можно писать практически любой код, возвращающий данные
*/
return DateTime.Now;
});
Внутри делегата доступны переменные и методы, определённые за его пределами:
int x = 0;
var MySlowToConstructObject = UtilsCache.GetCachedMethod(
"KEY_IN_CACHE",
DateTime.Now.AddSeconds(300),
new CacheDependency(HostingEnvironment.MapPath("~/Web.config")),
delegate()
{
int y = x + 1;
return y;
});
