Cache Access Pattern Revised

Karl Seguin has an interesting post about using System.Func to fight repetitive code blocks, which actually addresses a pain point I’ve had for quite some time but had never acted on to fix. Whenever one access the Cache or a similar statebag that might or might not contain the value sought after, it is important to check if the value exists first, and if it doesn’t, go and retrieve it from wherever its authoritative repository is (typically the database). This can be done poorly, so I show the correct way to do it frequently in my talks about caching or performance. The unfortunate thing about this pattern, however, is that you’re always stuck writing the same code, which gets old after a while (and is prone to error).

Karl shows how one can refactor the object fetching method to accept a callback which is responsible for fetching the object if it is not in the cache/statebag, using Func<T>. The resulting code looks like this:

Assuming that we want a method that retrieves a user from its ID, and that fetching it from the data store requires a call to _dataStore.GetUserFromId(userId), we can write our data access method like so:

In this example, () => is a parameterless delegate. Essentially we’re wrapping up the little bit of code required to fetch the user (or whatever object) and passing it into the method that is responsible for checking the cache. If the object is not in the cache, the function is executed (otherwise it is ignored).

Looking around a bit more, Alan Northam has a somewhat similar, but more involved caching pattern here, which does a little more error checking and uses a standard delegate for the retrieveMethod. Be sure to have a look at that as well – it would be easy to modify it to use Func<T>.

kick it on

  • karl

    You changed the param name to ifNullRetrievalMethod, but are still using callback() in the actual code.

  • ssmith

    Thanks for that, Karl – it’s updated now. Any thoughts on that name, versus some of the others kicked around in your post’s comments?

  • David Penton

    Steve, I had written this to work before Func<t> was so popular. But it certainly is the right pattern:…</t>