All of our code interacting with the cache is on the form
string key = “persons”
var cache = SimpleCache.Instance;
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
—
<!–
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 using\cf0 System.Threading;\par ??\cf1 using\cf0 NUnit.Framework;\par ??\par ??\cf1 namespace\cf0 Business.Test\par ??\{\par ?? [\cf4 TestFixture\cf0 ]\par ?? \cf1 public\cf0 \cf1 class\cf0 \cf4 TestLambdas\par ??\cf0 \{\par ?? [\cf4 Test\cf0 ]\par ?? \cf1 public\cf0 \cf1 void\cf0 TestLamda()\par ?? \{\par ?? \cf1 var\cf0 serv = \cf1 new\cf0 \cf4 Serv\cf0 ();\par ?? \cf1 var\cf0 s1 = serv.GetCurrentMillis();\par ?? \cf4 Thread\cf0 .Sleep(20);\par ?? \cf1 var\cf0 s2 = serv.GetCurrentMillis();\par ?? \cf4 Assert\cf0 .AreEqual(s1, s2);\par ?? \}\par ??\par ?? [\cf4 Test\cf0 ]\par ?? \cf1 public\cf0 \cf1 void\cf0 TestLamda2()\par ?? \{\par ?? \cf1 var\cf0 serv = \cf1 new\cf0 \cf4 Serv\cf0 ();\par ?? \cf1 var\cf0 s1 = serv.GetRandomString(10);\par ?? \cf4 Thread\cf0 .Sleep(20);\par ?? \cf1 var\cf0 s2 = serv.GetRandomString(10);\par ?? \cf4 Assert\cf0 .AreEqual(s1, s2);\par ?? \cf4 Thread\cf0 .Sleep(20);\par ?? \cf1 var\cf0 s3 = serv.GetRandomString(10);\par ?? \cf4 Assert\cf0 .AreEqual(s2, s3);\par ?? \}\par ?? \}\par ??\par ?? \cf1 public\cf0 \cf1 class\cf0 \cf4 Serv\par ??\cf0 \{ \par ?? \cf1 public\cf0 \cf1 string\cf0 GetRandomString(\cf1 int\cf0 max_rand)\par ?? \{\par ?? \cf1 return\cf0 CacheFetch(\cf5 “rand”\cf0 , () => \cf5 “rand”\cf0 +\cf1 new\cf0 \cf4 Random\cf0 ().Next(max_rand) ,5);\par ?? \}\par ?? \cf1 public\cf0 \cf1 int\cf0 GetCurrentMillis()\par ?? \{\par ?? \cf1 return\cf0 CacheFetch(\cf5 “day”\cf0 , () => \cf4 DateTime\cf0 .Now.Millisecond, 5);\par ?? \}\par ??\par ?? \cf1 public\cf0 \cf1 delegate\cf0 T \cf4 Fetch\cf0 ();\par ??\par ?? \cf1 public\cf0 T CacheFetch(K key, \cf4 Fetch\cf0 fetcher, \cf1 int\cf0 cacheMinutes)\par ?? \{\par ?? \cf1 var\cf0 cache = \cf4 SimpleCache\cf0 .Instance;\par ?? \cf1 if\cf0 (cache.Exists(key) && !cache.HasExpired(key))\par ?? \{\par ?? \cf1 return\cf0 cache.GetItem(key);\par ?? \}\par ?? \cf1 var\cf0 retVal = fetcher();\par ?? cache.AddItem(key, retVal, cacheMinutes);\par ?? \cf1 return\cf0 retVal;\par ?? \}\par ?? \}\par ??\}}
–>
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();
public T CacheFetch(K key, Fetch fetcher, int cacheMinutes)
{
var cache = SimpleCache.Instance;
if (cache.Exists(key) && !cache.HasExpired(key))
{
return cache.GetItem(key);
}
var retVal = fetcher();
cache.AddItem(key, retVal, cacheMinutes);
return retVal;
}
}
}