DynaCache is a small C# library that allows you to automatically cache the output from standard .NET functions. Although it is possible to use it without one, DynaCache works best when used in conjunction with a dependency injection (DI) framework, such as StructureMap, Ninject, etc.

The easiest way to explain it is by example, so without further ado…

A quick demonstration

Say you have the following class:

public class TestClass : ITestClass
{
    public string GetData(int id)
    {
        // Load some data from somewhere
        return this.dataRepository.GetById(id);
    }
}

Mark the GetData method as virtual and add a CacheableMethod attribute to it, indicating the length of time the result of the method should be kept in the cache (in seconds):

[CacheableMethod(30)]
public virtual string GetData(int id) 

In your DI setup, add the following: (this example is using a Ninject kernel)

kernel.Bind<IDynaCacheService>().To<MemoryCacheService>().InSingletonScope();
kernel.Bind<ITestClass>().To(Cacheable.CreateType<TestClass>());

The first line configures the cache service that DynaCache will use to store and retrieve cached values, the concrete implementation being DynaCache’s built-in MemoryCacheService, whilst the second binds ITestClass to a cacheable version of TestClass constructed by DynaCache. Very important: When you're using the MemoryCacheService as your cache, you need to make sure it's registered in singleton scope, otherwise you'll end up with a different cache each time a new cacheable class is created!

And that’s all you have to do! Whenever an instance of ITestClass is used, the results of calling GetData with a given id will automatically be obtained from the cache if they exist, or read from the repository if they don’t.

Configuring cache durations in app.config/web.config

As of v1.07,  the CacheableMethod attribute can be passed a named cache duration, e.g.:

[CacheableMethod("long")]
public virtual string GetData(int id) 

The named caches can be configured in your application config like this:

<configSections>
  <section name="dynaCache" type="DynaCache.DynaCacheSection, DynaCache"/>
</configSections>

<dynaCache>
  <cacheDurations>
    <add name="short" duration="00:00:01" />
    <add name="long" duration="00:01:00" />
  </cacheDurations>
</dynaCache> 

Obviously the names of the caches are completely up to you; you don't have to stick with "short" and "long"!

Guidelines for usage

Not all methods are good candidates for caching – here are some guidelines for things to watch out for:

  • Keep the number of parameters on cacheable methods down if at all possible – the more parameter combinations there are the less likely it is that caching will help you.
  • Don’t try to cache the results of methods that take very long strings as input parameters – the actual parameter values are used to formulate the unique cache key for a method call, so that long text will become part of that key.
  • Parameter types other than .NET primitives (int, long, decimal,string, etc.) aren’t supported unless you overload the ToString method of the type to return a uniquely identifying value for the type. Even then, they should probably be shied away from unless you’re completely comfortable with what’s actually going on “under the hood”.

How it works

DynaCache generates a class that derives from TestClass that in C# would look something like this:

public class CacheableTestClass : TestClass
{
    private IDynaCacheService cacheService;
    
    public TestClass(IDynaCacheService cacheService)
    {
        this.cacheService = cacheService;
    }

    public override string GetData(int id)
    {
        string cacheKey = String.Format(CultureInfo.InvariantCulture, "TestClass_GetData(Int32).{0}", id);
        object result;
        if (!this.cacheService.TryGetCachedObject(cacheKey, out result))
        {
            result = base.GetData(id);
            this.cacheService.SetCachedObject(cacheKey, result, 200);
        }
        
        return (string)result;
    }
}

This type is generated using Reflection Emit method and exist as an in-memory dynamic assembly.

Installing DynaCache

DynaCache is available as a Nuget package.

More Resources

DynaCache - just like page output caching, but for classes - an article that goes over th basic principles discussed above. 

Last edited Jul 23, 2014 at 6:49 PM by MikeGoatly, version 7