Introducing Attribute Based Caching

"There are only two hard problems in computer science: cache invalidation, naming things, and off-by-one errors."

I am a big fan of postsharp and its creator Gael.  There are a number of examples floating around of doing caching with postsharp.  However, none handled cache invalidation in a nice declarative way.  


I have released a caching library that uses postsharp on codeplex.

http://cache.codeplex.com/

It has some neat attribute based cache invalidation features and can use an in-memory cache or velocity.

Features:

  • Configurable Cache Store (Options include In-process and Out-Of-Process and Off. Out-Of-Process uses Microsoft ApplicationServer.Caching)
  • Declarative Caching & Declarative Cache Invalidation ( use method name or configurable “GroupName” plus method parameters to cache & trigger cache invalidation)

Simple Example( No invalidation):

[Cache.Cacheable] //this method now cached, will only be called once per guid
public SomeExpensiveObject GetExpensiveObject(Guid userId)
{
..
}

Full Featured Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CacheAspect.Attributes;

namespace TestCache
{
    class UserRepository
    {
        //Get All Users is cached in Key = "GetAllUsers"
        [Cache.Cacheable("GetAllUsers")] 
        List<User> GetAllUsers()
        {
            ...
        }

        //GetUserById is cached using "GetUserById" + ID parameter
        [Cache.Cacheable("GetUserById")]
        User GetUserById(int Id)
        {
            ...
        }

        //Add user invalidates "GetAllUsers" cache key (User parameter is ignored)
        [Cache.TriggerInvalidation("GetAllUsers"CacheSettings.IgnoreParameters)]
        void AddUser(User user)
        {

        }

        //Delete user invalidates both GetAllUsers & GetUserById
        //The user parameters Id property is used to build Key for "GetUserById"+ Id  Key
        //this is done using a bit reflection
        [Cache.TriggerInvalidation("GetAllUsers"CacheSettings.IgnoreParameters)]
        [Cache.TriggerInvalidation("GetUserById"CacheSettings.UseId)]
        void DeleteUser(User user)
        {
            ...
        }
      
    }
}

http://cache.codeplex.com/SourceControl/changeset/view/1505#25143  

This example shows how an expensive object (user in this case) might be cached at the repository level.  It shows how attributes can be used to clear from the cache stale objects based on add update and delete changes in a declarative fashion. 

Please excuse the empty method bodies for now.  I will have a better sample project put together at some point.

Notes

  1. adamgbell posted this