I took the βAnswerβ and modified it to make the CacheExtensions class static and suggest a slight change so that Func<T> be null :
public static class CacheExtensions { private static object sync = new object(); public const int DefaultCacheExpiration = 20; /// <summary> /// Allows Caching of typed data /// </summary> /// <example><![CDATA[ /// var user = HttpRuntime /// .Cache /// .GetOrStore<User>( /// string.Format("User{0}", _userId), /// () => Repository.GetUser(_userId)); /// /// ]]></example> /// <typeparam name="T"></typeparam> /// <param name="cache">calling object</param> /// <param name="key">Cache key</param> /// <param name="generator">Func that returns the object to store in cache</param> /// <returns></returns> /// <remarks>Uses a default cache expiration period as defined in <see cref="CacheExtensions.DefaultCacheExpiration"/></remarks> public static T GetOrStore<T>( this Cache cache, string key, Func<T> generator ) { return cache.GetOrStore( key, (cache[key] == null && generator != null) ? generator() : default( T ), DefaultCacheExpiration ); } /// <summary> /// Allows Caching of typed data /// </summary> /// <example><![CDATA[ /// var user = HttpRuntime /// .Cache /// .GetOrStore<User>( /// string.Format("User{0}", _userId), /// () => Repository.GetUser(_userId)); /// /// ]]></example> /// <typeparam name="T"></typeparam> /// <param name="cache">calling object</param> /// <param name="key">Cache key</param> /// <param name="generator">Func that returns the object to store in cache</param> /// <param name="expireInMinutes">Time to expire cache in minutes</param> /// <returns></returns> public static T GetOrStore<T>( this Cache cache, string key, Func<T> generator, double expireInMinutes ) { return cache.GetOrStore( key, (cache[key] == null && generator != null) ? generator() : default( T ), expireInMinutes ); } /// <summary> /// Allows Caching of typed data /// </summary> /// <example><![CDATA[ /// var user = HttpRuntime /// .Cache /// .GetOrStore<User>( /// string.Format("User{0}", _userId),_userId)); /// /// ]]></example> /// <typeparam name="T"></typeparam> /// <param name="cache">calling object</param> /// <param name="key">Cache key</param> /// <param name="obj">Object to store in cache</param> /// <returns></returns> /// <remarks>Uses a default cache expiration period as defined in <see cref="CacheExtensions.DefaultCacheExpiration"/></remarks> public static T GetOrStore<T>( this Cache cache, string key, T obj ) { return cache.GetOrStore( key, obj, DefaultCacheExpiration ); } /// <summary> /// Allows Caching of typed data /// </summary> /// <example><![CDATA[ /// var user = HttpRuntime /// .Cache /// .GetOrStore<User>( /// string.Format("User{0}", _userId), /// () => Repository.GetUser(_userId)); /// /// ]]></example> /// <typeparam name="T"></typeparam> /// <param name="cache">calling object</param> /// <param name="key">Cache key</param> /// <param name="obj">Object to store in cache</param> /// <param name="expireInMinutes">Time to expire cache in minutes</param> /// <returns></returns> public static T GetOrStore<T>( 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 this step again to implement a test session solution that extends the abstract class System.Web.HttpSessionStateBase.
public static class SessionExtension { /// <summary> /// /// </summary> /// <example><![CDATA[ /// var user = HttpContext /// .Session /// .GetOrStore<User>( /// string.Format("User{0}", _userId), /// () => Repository.GetUser(_userId)); /// /// ]]></example> /// <typeparam name="T"></typeparam> /// <param name="cache"></param> /// <param name="key"></param> /// <param name="generator"></param> /// <returns></returns> public static T GetOrStore<T>( this HttpSessionStateBase session, string name, Func<T> generator ) { var result = session[name]; if ( result != null ) return (T)result; result = generator != null ? generator() : default( T ); session.Add( name, result ); return (T)result; } }
njappboy Jun 09 '09 at 8:35 2009-06-09 08:35
source share