I\'d like to cache objects in ASP.NET MVC. I have a BaseController that I want all Controllers to inherit from. In the BaseController there is a User
I took Will's answer and modified it to make the CacheExtensions class static and to suggest a slight alteration in order to deal with the possibility of Func being null :
public static class CacheExtensions
{
private static object sync = new object();
public const int DefaultCacheExpiration = 20;
///
/// Allows Caching of typed data
///
/// (
/// string.Format("User{0}", _userId),
/// () => Repository.GetUser(_userId));
///
/// ]]>
///
/// calling object
/// Cache key
/// Func that returns the object to store in cache
///
/// Uses a default cache expiration period as defined in
public static T GetOrStore( this Cache cache, string key, Func generator ) {
return cache.GetOrStore( key, (cache[key] == null && generator != null) ? generator() : default( T ), DefaultCacheExpiration );
}
///
/// Allows Caching of typed data
///
/// (
/// string.Format("User{0}", _userId),
/// () => Repository.GetUser(_userId));
///
/// ]]>
///
/// calling object
/// Cache key
/// Func that returns the object to store in cache
/// Time to expire cache in minutes
///
public static T GetOrStore( this Cache cache, string key, Func generator, double expireInMinutes ) {
return cache.GetOrStore( key, (cache[key] == null && generator != null) ? generator() : default( T ), expireInMinutes );
}
///
/// Allows Caching of typed data
///
/// (
/// string.Format("User{0}", _userId),_userId));
///
/// ]]>
///
/// calling object
/// Cache key
/// Object to store in cache
///
/// Uses a default cache expiration period as defined in
public static T GetOrStore( this Cache cache, string key, T obj ) {
return cache.GetOrStore( key, obj, DefaultCacheExpiration );
}
///
/// Allows Caching of typed data
///
/// (
/// string.Format("User{0}", _userId),
/// () => Repository.GetUser(_userId));
///
/// ]]>
///
/// calling object
/// Cache key
/// Object to store in cache
/// Time to expire cache in minutes
///
public static T GetOrStore( this Cache cache, string key, T obj, double expireInMinutes ) {
var result = cache[key];
if ( result == null ) {
lock ( sync ) {
result = cache[key];
if ( result == null ) {
result = obj != null ? obj : default( T );
cache.Insert( key, result, null, DateTime.Now.AddMinutes( expireInMinutes ), Cache.NoSlidingExpiration );
}
}
}
return (T)result;
}
}
I would also consider taking this a step further to implement a testable Session solution that extends the System.Web.HttpSessionStateBase abstract class.
public static class SessionExtension
{
///
///
///
/// (
/// string.Format("User{0}", _userId),
/// () => Repository.GetUser(_userId));
///
/// ]]>
///
///
///
///
///
public static T GetOrStore( this HttpSessionStateBase session, string name, Func generator ) {
var result = session[name];
if ( result != null )
return (T)result;
result = generator != null ? generator() : default( T );
session.Add( name, result );
return (T)result;
}
}