Joe

Mister Doctor Professor
posts - 23, comments - 19, trackbacks - 134

HTTP Cache Helper With a Fluent Interface

After writing the same 20 lines of boilerplate code for the 1000th time, I decided to encapsulate it in a class and add some syntactic sweetness to it in the form of a fluent interface as recently demonstrated by Joey Beninghove

What I had been doing was something like the following pseudocode (or a slight variation) in every place I wanted to cache something.

declare returnObject as null

if the HTTPCache available
    if the object is available in the cache
        set returnObject
    else
        set returnObject to whatever code is needed to get the object
        add returnObject to the cache
else
  set returnObject to whatever code is needed to get the object

return returnObject  
        
   
    

 

Here is the class I ended up with.

 

public class HTTPCacheHelper<T>
 {
     private DateTime? _AbsoluteExpiration;
     private TimeSpan? _SlidingExpiration;
     private CacheItemPriority _Priority = CacheItemPriority.Default;
     private string _Key;

     /// <summary>
     /// Key of item stored in the cache.
     /// </summary>
     public HTTPCacheHelper<T> WithKeyOf(string key)
     {
         _Key = key;
         return this;
     }

     /// <summary>
     /// Absolute date to expire on
     /// </summary>
     /// <remarks>
     /// Optional, but either this or WithSlidingExpiration must be called
     /// </remarks>
     public HTTPCacheHelper<T> WithExpirationDateOf(DateTime expires)
     {
         _AbsoluteExpiration = expires;
         return this;
     }

     /// <summary>
     /// Sliding timespan to expire on.
     /// </summary>
     /// <remarks>
     /// Optional, but either this or WithExpirationDateOf must be called
     /// </remarks>
     public HTTPCacheHelper<T> WithSlidingExpiration(TimeSpan ts)
     {
         _SlidingExpiration = ts;
         return this;
     }

     /// <summary>
     /// Priority
     /// </summary>
     public HTTPCacheHelper<T> WithPriorityOf(CacheItemPriority priority)
     {
         _Priority = priority;
         return this;
     }

     /// <summary>
     /// Adds the item to the cache based data passed in in previous methods.  
     /// This will the last method call in the chain, and must
     /// be called in order to for the item to be cached.
     /// </summary>
     public void Commit(T item)
     {
         Debug.Assert(!item.Equals(default(T)));
         Debug.Assert(!_AbsoluteExpiration.HasValue ^ _SlidingExpiration.HasValue);
         Debug.Assert(!string.IsNullOrEmpty(_Key));

         if (!_AbsoluteExpiration.HasValue) _AbsoluteExpiration = Cache.NoAbsoluteExpiration;
         if (!_SlidingExpiration.HasValue) _SlidingExpiration = Cache.NoSlidingExpiration;

         lock (HttpRuntime.Cache)
         {
             HttpRuntime.Cache.Add(_Key, item, null, _AbsoluteExpiration.Value, _SlidingExpiration.Value, _Priority, null);
         }
     }


     public  T GetItem(string key)
     {
         if (HttpRuntime.Cache != null)
         {
             object check = HttpRuntime.Cache[key];

             if (check != null)
             {
                 return (T)check;
             }
         }

         return default(T);
     }

     private bool IsNull(T item)
     {
         if (typeof(T).IsValueType)
         {
             return default(T).Equals(item);
         }
         else
         {
             return item == null;
         }

     }


     public  T GetItem(string key, Func<T> itemSourceOnDoesNotExist)
     {
         T check = GetItem(key);

         if (IsNull(check))
         {
             check = itemSourceOnDoesNotExist();
         }

         return check;
     }

     public  T GetItem(string key, Func<T> itemSourceOnDoesNotExist, Proc<T> addToCache)
     {
         T check = GetItem(key);

         if (IsNull(check))
         {
             check = itemSourceOnDoesNotExist();
             addToCache(check);
         }
         return check;
     }
     
 }

 

The methods prior to Commit() make up the fluent interface, and I stole a little code from Ayende's Rhino Commons for the delegates in the GetItem methods.  As a side note, the GetItems methods were originally static, which allowed me to do the following: 

 

private string ItemToCache()
{
    return "expected value";
}


[Test]
public void FluentSyntaxText()
{
    HTTPCacheHelper<string> cache = new HTTPCacheHelper<string>();

    cache
        .WithExpirationDateOf(DateTime.Now.AddDays(1))
        .WithKeyOf("TestKey")
        .WithPriorityOf(CacheItemPriority.Low)
        .Commit(ItemToCache());

    string actualValue = HTTPCacheHelper<string>.GetItem("TestKey", ItemToCache, cache.Commit);

    Assert.AreEqual("expected value", actualValue);

}

 

But it dawned on me a little later that by making them instance methods I could accomplish the same thing in a single statement 

 

[Test] 
public void FluentSyntaxTest2()
{
    HTTPCacheHelper<string> cache = new HTTPCacheHelper<string>();

    string actualValue = cache
        .WithExpirationDateOf(DateTime.Now.AddDays(1))
        .WithKeyOf("TestKey")
        .WithPriorityOf(CacheItemPriority.Low)
        .GetItem("TestKey", ItemToCache, cache.Commit);

    Assert.AreEqual("expected value", actualValue);

}

 

Which is pretty friggin' sweet.

Print | posted on Thursday, September 13, 2007 11:43 PM |

Feedback

Gravatar

# re: HTTP Cache Helper With a Fluent Interface

Good stuff. Love to see folks getting creative in their code.
9/14/2007 10:00 AM | Joey Beninghove
Gravatar

# Free blowjob.

How to give a blowjob. Blowjob. Cow blowjob. Hot blowjob movies. Free blowjob videos.
8/12/2008 5:27 PM | Blowjob video clips free samples.
Gravatar

# Animal sex stories animal.

Animal sex stories. Animal sex free. Animal scat sex. Free animal sex stories. Animal sex. Free animal sex videos. Free animal sex movies.
8/13/2008 6:00 AM | Animal sex with human.
Gravatar

# Angelina jolie fan fic.

Angelina jolie nude. Pictures of angelina jolie. Angelina jolie. Nude pictures of angelina jolie. October 22 2003 angelina jolie.
8/20/2008 8:58 PM | Angelina jolie.
Gravatar

# Free blowjob pics.

Blowjob tutorials. How to give a blowjob. Blowjob. Blowjob techniques. Free blowjob pics. Blowjob movie.
9/16/2008 7:50 PM | Blowjob video.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 5 and 7 and type the answer here:

Powered by: