C# HttpRuntime - Simple Cache
I have been working recently on an application that needs very simple caching. I found this code sometime ago (but can’t for the life of me remember where! I think it may have been on StackOverflow). It is a simple cache that uses the HttpRuntime which enables it to be used on the web and also the desktop. This code has saved my bacon on more than one occasion so I thought I would share it.
public interface ICacheService
{
T Get<T>(string cacheId, Func<T> getItemCallback, int secondsToCache) where T : class;
void Delete(string cacheId);
}
There are two very simple methods. The get method takes a cache identifier which is used to identify the object in the cache, a delegate which is used to set the object in the cache and an integer which denotes the number of seconds to cache the item for. The get method will first check to see if the item is in the cache and if it is then the item will be returned. If the item is not in the cache (due to the item never being added or it is expired) then the item will be added to the cache and then returned. Get is a generic method and will return whichever type is returned by the delegates encapsulated method.
The delete method will remove an item from the cache using the cacheId passed in.
public class WebCache : ICacheService
{
public T Get<T>(string cacheId, Func<T> getItemCallback, int secondsToCache) where T : class
{
T item = HttpRuntime.Cache.Get(cacheId) as T;
if (item == null)
{
item = getItemCallback();
HttpRuntime.Cache.Insert(cacheId,
item,
null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
new TimeSpan(0, 0, secondsToCache),
CacheItemPriority.Normal,
null);
}
return item;
}
public void Delete(string cacheId)
{
HttpRuntime.Cache.Remove(cacheId);
}
}
Example Usage
Below I have a very simple POCO which has a few properties and I have overridden ToString to make it simpler to write the information out to the console.
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public DateTime LastAccessed { get; set; }
public override string ToString()
{
return string.Format("PersonId : {0} - Name : {1} - Last Accessed {2}", PersonId, Name, LastAccessed);
}
}
I also have a fake repository which has one method Get() which will return a Person.
public class PersonRepository
{
public Person Get()
{
return new Person {PersonId = 1, Name = "Jimmy Smith", LastAccessed = DateTime.Now};
}
}
Below I instantiate an instance of the cache can then begin to call the Get method to add and retrieve items from the cache setting the cache duration to different intervals. By putting the thread to sleep I can either let the cache expire or stay alive.
class Program
{
static void Main(string[] args)
{
WebCache cache = new WebCache();
Person person = cache.Get("_time", () => new PersonRepository().Get(), 3);
Console.WriteLine(person);
System.Threading.Thread.Sleep(2000);
person = cache.Get("_time", () => new PersonRepository().Get(), 3);
Console.WriteLine(person);
System.Threading.Thread.Sleep(4000);
person = cache.Get("_time", () => new PersonRepository().Get(), 3);
Console.WriteLine(person);
System.Threading.Thread.Sleep(2000);
person = cache.Get("_time", () => new PersonRepository().Get(), 10);
Console.WriteLine(person);
cache.Delete("_time");
person = cache.Get("_time", () => new PersonRepository().Get(), 10);
Console.WriteLine(person);
Console.ReadLine();
}
}
I have found this to be a really useful caching implementation when my caching needs and server architecture is simple and straight forward's.
Download the code example here