string key = "persons"
var cache = SimpleCache
if(cache.Exists(key) && !HasExpired(Key)
{
return cache.Get(key);
}
else
{
int timeout_in_minutes = 5;
var persons = PersonDAO.GetAllPersons();
cache.Add(persons, timeout_in_minutes)
return persons;
}
---
So it's pretty tedious code to write, but relatively short and sweet. somewhat easy to introduce errors in the cache logic (which really should be the cache's responsibility after all)
I decided I would try to write one that would be easier to consume, and here is code
showing what I ended up with. The tests run as expected, I will leave it up to the reader
(if I indeed have any) to figure out how CacheFetch gets stuff done, I found it to be pretty
(yet a bit hard to grok) code that exemplifies the use of lambda-expressions and how a lambda
can access variables that were present where it was defined, in addition to those present (in the form of input params) where it is executed
--
using System.Threading;
using NUnit.Framework;
namespace Business.Test
{
[TestFixture]
public class TestLambdas
{
[Test]
public void TestLamda()
{
var serv = new Serv();
var s1 = serv.GetCurrentMillis();
Thread.Sleep(20);
var s2 = serv.GetCurrentMillis();
Assert.AreEqual(s1, s2);
}
[Test]
public void TestLamda2()
{
var serv = new Serv();
var s1 = serv.GetRandomString(10);
Thread.Sleep(20);
var s2 = serv.GetRandomString(10);
Assert.AreEqual(s1, s2);
Thread.Sleep(20);
var s3 = serv.GetRandomString(10);
Assert.AreEqual(s2, s3);
}
}
public class Serv
{
public string GetRandomString(int max_rand)
{
return CacheFetch("rand", () => "rand"+new Random().Next(max_rand) ,5);
}
public int GetCurrentMillis()
{
return CacheFetch("day", () => DateTime.Now.Millisecond, 5);
}
public delegate T Fetch<T>();
public T CacheFetch<T, K>(K key, Fetch<T> fetcher, int cacheMinutes)
{
var cache = SimpleCache<K, T>.Instance;
if (cache.Exists(key) && !cache.HasExpired(key))
{
return cache.GetItem(key);
}
var retVal = fetcher();
cache.AddItem(key, retVal, cacheMinutes);
return retVal;
}
}
}