Transparently Caching Queries

The How and the What are often discussed when it comes to caching. As always, there is no Silver Bullet that solves all issues at once.

TecX offers one solution for the following scenario: Say you have a datasource that provides access to your data via a set of IQueryable<T> properties. The interface might look like this:

public interface ICustomerRepository
{
  IQueryable<Customer> Customers { get; }
}

Now you want to add caching but you don’t want to have to change how the consumers work with that repository. So you need some transparent caching mechanism that isolates your consumers (and your developers) from the actual implementation of caching. You are then able to run your application without caching or you can use the new features from System.Runtime.Caching, the AppFabric Cache or something completely different.

Two classes from TecX.Caching (namely QueryInterceptor and QueryInterceptorProvider) allow for transparent interception of queries against an IQueryable<T>. They are wrappers for IQueryable and IQueryProvider that use the Expression property of the IQueryable to generate a unique cache key. A simple ToString() operation won’t give you a key that is “uniqe enough” so a technique presented by Pete Montgomery is used to partially evaluate the expression tree of the query.

The sample CachingCustomerRepository demonstrates how this interception can be used to introduce a transparent caching layer into your application and swap it out for arbitrary implementations using different caching technologies at any time.

public class CachingCustomerRepository : ICustomerRepository
{
  private readonly ICustomerRepository inner;
  private readonly ObjectCache cache;
  private readonly QueryInterceptor<Customer> customers;
  private readonly ExpirationToken expirationToken;
  public CachingCustomerRepository(ICustomerRepository inner)
  {
    this.inner = inner;
    this.cache = new MemoryCache(typeof(CachingCustomerRepository).Name);
    this.customers = new QueryInterceptor<Customer>(this.inner.Customers);
    this.customers.QueryProvider.Executing += this.OnQueryExecuting;
    this.customers.QueryProvider.Executed += this.OnQueryExecuted;
    this.expirationToken = new ExpirationToken();
  }
  public IQueryable<Customer> Customers { get { return this.customers; } }
  public void Add(Customer customer)
  {
    this.inner.Add(customer);
    this.expirationToken.Expire();
  }
  private void OnQueryExecuted(object sender, ExpressionExecuteEventArgs e)
  {
    IQueryable<Customer> cachedResult = this.cache[e.CacheKey] as IQueryable<Customer>;
    if (cachedResult == null)
    {
      var evaluatedQueryable = ((IEnumerable<Customer>)e.Result).ToList().AsQueryable();
      CacheItem cacheItem = new CacheItem(e.CacheKey, evaluatedQueryable);
      CacheItemPolicy policy = new CacheItemPolicy { SlidingExpiration = 1.Minutes() };
      ExternallyControlledChangeMonitor monitor = new ExternallyControlledChangeMonitor
        {
          ExpirationToken = this.expirationToken
        };
      policy.ChangeMonitors.Add(monitor);
      this.cache.Add(cacheItem, policy);
    }
  }
  private void OnQueryExecuting(object sender, ExpressionExecuteEventArgs e)
  {
    IQueryable<Customer> cachedResult = this.cache[e.CacheKey] as IQueryable<Customer>;
    if (cachedResult != null)
    {
      e.Handled = true;
      e.Result = cachedResult;
    }
  }
}

Using a framework like Moq you can easily mock your actual data access in order to run tests against your cache.

var mock = new Mock<ICustomerRepository>();
mock.SetupGet(r => r.Customers).Returns(
new[]
{
  new Customer { Id = 1, Name = "1" },
  new Customer { Id = 2, Name = "2" },
  new Customer { Id = 3, Name = "3" }
}.AsQueryable());
var cache = new CachingCustomerRepository(mock.Object);

// Actual testing code

mock.VerifyGet(r => r.Customers, Times.Once());

At the heart of the CachingCustomerRepository are the QueryInterceptor (comes in a generic and a non-generic version)

public class QueryInterceptor<T> : QueryInterceptor, IQueryable<T>
{
  public QueryInterceptor(IQueryable<T> wrapped)
    : this(wrapped, new QueryInterceptorProvider(wrapped.Provider))
  {
  }
  public QueryInterceptor(IQueryable<T> wrapped, QueryInterceptorProvider provider)
    : base(wrapped, provider)
  {
  }
  public IEnumerator<T> GetEnumerator()
  {
    var enumerable = this.Provider.Execute<IEnumerable<T>>(this.Expression);
    var enumerator = enumerable.GetEnumerator();
    return enumerator;
  }
}
public class QueryInterceptor : IQueryable
{
  private readonly IQueryable wrapped;
  private readonly QueryInterceptorProvider queryProvider;
  public QueryInterceptor(IQueryable wrapped, QueryInterceptorProvider provider)
  {
    this.wrapped = wrapped;
    this.queryProvider = provider;
  }
  public Type ElementType { get { return this.wrapped.ElementType; } }
  public Expression Expression { get { return this.wrapped.Expression; } }
  public IQueryProvider Provider { get { return this.queryProvider; } }
  public QueryInterceptorProvider QueryProvider { get { return this.queryProvider; } }
  IEnumerator IEnumerable.GetEnumerator()
  {
    var enumerable = (IEnumerable)this.Provider.Execute(this.Expression);
    var enumerator = enumerable.GetEnumerator();
    return enumerator;
  }
}

and the QueryInterceptorProvider.

public class QueryInterceptorProvider : IQueryProvider
{
  private readonly IQueryProvider wrapped;
  public QueryInterceptorProvider(IQueryProvider wrapped)
  {
    this.wrapped = wrapped;
  }
  public event EventHandler<ExpressionExecuteEventArgs> Executing = delegate { };
  public event EventHandler<ExpressionExecuteEventArgs> Executed = delegate { };
  public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
  {
    var rawQuery = this.wrapped.CreateQuery<TElement>(expression);
    var interceptor = new QueryInterceptor<TElement>(rawQuery, this);
    return interceptor;
  }
  public IQueryable CreateQuery(Expression expression)
  {
    var rawQuery = this.wrapped.CreateQuery(expression);
    var interceptor = new QueryInterceptor(rawQuery, this);
    return interceptor;
  }
  public TResult Execute<TResult>(Expression expression)
  {
    string cacheKey = expression.GetCacheKey();
    object value;
    bool handled = this.NotifyExecuting(expression, cacheKey, out value);
    TResult result = !handled ? this.wrapped.Execute<TResult>(expression) : (TResult)value;
    this.NotifyExecuted(expression, cacheKey, result);
    return result;
  }
  public object Execute(Expression expression)
  {
    string cacheKey = expression.GetCacheKey();
    object value;
    bool handled = this.NotifyExecuting(expression, cacheKey, out value);
    object result = !handled ? this.wrapped.Execute(expression) : value;
    this.NotifyExecuted(expression, cacheKey, result);
    return result;
  }
  private bool NotifyExecuting(Expression expression, string cacheKey, out object result)
  {
    var e = new ExpressionExecuteEventArgs
      {
        Expression = expression,
        CacheKey = cacheKey
      };
    this.Executing(this, e);
    if (e.Handled)
    {
      result = e.Result;
      return true;
    }
    result = null;
    return false;
  }
  private void NotifyExecuted(Expression expression, string cacheKey, object result)
  {
    var e = new ExpressionExecuteEventArgs
      {
        Expression = expression,
        CacheKey = cacheKey,
        Result = result
      };
    this.Executed(this, e);
   }
}

The code above illustrates one possible solution for one problem: How can I introduce a completely transparent caching layer around my data access?

Explicit caching on the contrary allows you to optimize what you put in the cache and when. This video by the guys behind StackOverflow shows which performance improvements and hardware savings are possible when you make caching very explicit.

Whenever you introduce caching to your application there are some questions that need to be answered:

  • Do I really have to cache every query?
  • Can I reuse parts of my results?
  • Will I run this exact query often enough to justify caching?
  • What happens when data changes (e.g. by calling UpdateCustomer)?
  • How much does performance really improve by introducing caching?
  • Does caching have an influence on the consistency of my results?

Don’t use caching if you can’t reason that the benefits outweigh the costs. Caching can cause a lot of trouble if it’s not done the right way…

Get the source code for transparent caching here (project TecX.Caching and the test suite that shows how to use it in TecX.Caching.Test).

Advertisement

Inject Primitive Dependencies by Convention

Mark Seemann, author of the book Dependency Injection in .NET, has a nice article about the injection of Primitive Dependencies.

From a technical perspective I find the part where he configures Castle Windsor to use his custom conventions most interesting. When I come across such a feature that exists in another DI container but is not present in Unity I try to port that feature. And I have yet to find some piece of functionality that cannot be implemented easily with a few lines of code. Adding support for parameter conventions takes about ~250 LoC. Due to the differences in their respective architecture the Unity implementation is two-part: The core part of the convention implements the custom interface IDependencyResolverConvention the part that performs the actual work implements IDependencyResolverPolicy which comes as part of the Unity infrastructure.

These are the interfaces:

public interface IDependencyResolverConvention
{
  bool CanCreateResolver(IBuilderContext context, DependencyInfo dependency);
  IDependencyResolverPolicy CreateResolver(IBuilderContext context, DependencyInfo dependency);
}

public interface IDependencyResolverPolicy : IBuilderPolicy
{
  object Resolve(IBuilderContext context);
}

Using that newly created infrastructure (and a second convention that works like the ConnectionStringConvention described in the article) you can resolve classes that look like these:

public class TakesPrimitiveParameter
{
  public int Abc { get; set; }
  public TakesPrimitiveParameter(int abc)
  {
    this.Abc = abc;
  }
}
public class TakesConnectionStringParameter
{
  public string AbcConnectionString { get; set; }
  public TakesConnectionStringParameter(string abcConnectionString)
  {
    this.AbcConnectionString = abcConnectionString;
  }
}

The integer value abc will be read from the appSettings section of your config file. The ConnectionString abc will be read from the connectionStrings section.

public class AppSettingsConvention : IDependencyResolverConvention
{
  public bool CanCreateResolver(IBuilderContext context, DependencyInfo dependency)
  {
    return dependency.DependencyType == typeof(int);
  }
  public IDependencyResolverPolicy CreateResolver(IBuilderContext context, DependencyInfo dependency)
  {
    return new AppSettingsResolverPolicy(dependency.DependencyName, dependency.DependencyType);
  }
}

public class AppSettingsResolverPolicy : IDependencyResolverPolicy
{
  private readonly string name;
  private readonly Type targetType;
  public AppSettingsResolverPolicy(string name, Type targetType)
  {
    this.name = name;
    this.targetType = targetType;
  }
  public object Resolve(IBuilderContext context)
  {
    string setting = ConfigurationManager.AppSettings[this.name];
    return Convert.ChangeType(setting, this.targetType);
  }
}

Setting up the registrations is as easy as this:

var container = new UnityContainer().WithDefaultConventionsForLiteralParameters();
var foo = container.Resolve<TakesPrimitiveParameter>();

Or if you prefer to have more fine granular control over the used conventions you can add them one by one:

var container = new UnityContainer()
                 .WithConventionsForLiteralParameters(
                   new ConnectionStringConvention(),
                   new AppSettingsConvention());
var foo = container.Resolve<TakesPrimitiveParameter>();

Neat and as Mark puts it: If you stick to your conventions it will just keep working when your code base grows.

Get the source code for the convention based injection here (project TecX.Unity folder Literals and the test suite that shows how to use it in TecX.Unity.Test).

Auto-generated Factories with Unity

If you need to create objects after the initialization of your object graph by the container injecting factories is the way to go.

But defining factory interfaces and/or abstract base classes, implementing them and duplicating the knowledge your container already has does not make sense. For these scenarios Castle Windsor has it’s Typed Factory Facilities.

Define just the factory interface. Register it with the container and tell the container to generate an implementation for you. After all the implementation does not matter. Its a detail the consumers should not have to care about. If you need to forward runtime parameters like ConnectionStrings or file names the container takes care of that too.

With TecX.Unity.Factories you get the same set of features for Unity as well. All of a sudden using factories becomes as easy as this:

public interface IMyFactory
{
 IFoo Create(string name);
}
public interface IFoo
{
 string Name { get; }
}
public class Foo : IFoo
{
 public string Name { get; set; }
 public Foo(string name)
 {
 this.Name = name;
 }
}
var container = new UnityContainer();
container.RegisterType<IMyFactory>(new TypedFactory());
container.RegisterType<IFoo, Foo>();
var factory = container.Resolve<IMyFactory>();
var foo = factory.Create("some name");
Assert.AreEqual("some name", foo.Name);

This also works for property injection as long as you mark the property for injection by the container.

container.RegisterType<IFoo, Foo>(new InjectionProperty("Name"));

After a major overhaul of its internals the TypedFactory no longer relies on Castle DynamicProxy for the generation of the interface implementation. Unity brings its own powerful block for interception. It just insists that there has to be a target object for the interception pipeline. After integrating the technique used to generate lazy proxies auto-generating factories is now a Unity-only implementation.

Get the source code for the factory generation here (project TecX.Unity folder Factories and the test suite that shows how to use it in TecX.Unity.Factories.Test).

Generate strongly typed factory delegates

Unity provides automatic factories (delegates in the form Func<T>) out of the box. TecX adds TypedFactories. And now you can also tell the container to generate strongly typed factory delegates for you. Imagine you have the following definition of a factory delegate:

public delegate IUnitOfWork UnitOfWorkFactory(bool isReadOnly);

And a consumer of the delegate that looks something like this:

public class Consumer
{
  private readonly UnitOfWorkFactory factory;
  public Consumer(UnitOfWorkFactory factory)
  {
    this.factory = factory;
  }
  public UnitOfWorkFactory Factory { get { return this.factory; } }
  // [...]
}

What’s inside the IUnitOfWorkinterface does not matter. Its implementation is more interesting:

public class UnitOfWork : IUnitOfWork
{
  private readonly bool isReadOnly;
  public UnitOfWork(bool isReadOnly)
  {
    this.isReadOnly = isReadOnly;
  }
  public bool IsReadOnly { get { return this.isReadOnly; } }
  // [...]
}

Notice that the name of the parameter the delegate takes equals the name of the constructor parameter of UnitOfWork.

The following test runs green.

var container = new UnityContainer();
container.RegisterType<UnitOfWorkFactory>(new DelegateFactory());
container.RegisterType<IUnitOfWork, UnitOfWork>();
Consumer consumer = container.Resolve();
UnitOfWork uow = consumer.Factory(true) as UnitOfWork;
Assert.IsNotNull(uow);
Assert.IsTrue(uow.IsReadOnly);

That means that Unity generates a UnitOfWorkFactory delegate under the covers and injects it into the constructor of the Consumer class. The DelegateFactory also forwards the parameter you have to provide when calling the delegate.

So that’s yet another way not to write code for a factory.

Get the source code for the delegate generation here (project TecX.Unity folder Factories and the test suite that shows how to use it in TecX.Unity.Factories.Test).

Auto-generate NullObjects

NullObjects are a very usefull pattern. Among some other things they can be used as a means of defensive programming. If you have a dependency of a certain type (say ILogger) and don’t want make it an optional dependency using property injection (with the added downside of having to check for null every time you access that property) you can use a NullObject (in this case a NullLogger) to ensure that an instance of your interface is always present. Better prevent errors in the first place than telling people what they did wrong afterwards.

But do you really want to spend the time to implement classes that do … nothing?!

I consider DI containers (and infrastructure in general) a great tool to relieve programmers of the burden of routine tasks. Maybe that’s because I’m lazy and don’t want to do the same work twice.

A while ago Oren Eini announced a challenge for a Null Object Dependency Facility for Castle Windsor. I don’t know wether that challenge ever resulted in any actual code but I think its fun to solve that problem for Unity.

After some fiddling around with Reflection.Emit (again…) I am proud to announce that Unity can automatically generate and inject implementations even for trickier interfaces (like TryGetValue with out parameters). The generated code will never return null for strings or collections but empty strings and collections instead.

The functionality is accessible via an extension method for IUnityContainer.

public static IUnityContainer RegisterNullObject(this IUnityContainer container,
    Type contract, string name, LifetimeManager lifetime, 
    params InjectionMember[] injectionMembers)

Get the source code here (project TecX.Unity folder Proxies and the test suite that shows how to use it in TecX.Unity.Proxies.Test).

Generate lazy proxies on the fly

Imagine you have a service described by a contract IMyContract and an implementation thereof called MyService. That service is needed at several places throughout your application. The instantiation of MyService is expensive (e.g. takes a long time or consumes a lot of resources). In addition, that service is not needed all of the time (e.g. a message handler that calls this service or another depending on the content of a message).

If you apply the DI pattern you could inject a factory into your service consumers. That factory will only be called when a service instance is really needed. But wait! That is a leaky abstraction! You know that your implementation has a certain behavior and thus you change the way your application uses it. Another implementation of IMyContract might not show that behavior. And so you can’t interchange those implementations at will.

One solution would be to use the interception features of Unity or DynamicProxy to achieve some kind of lazy instantiation. But that is neither pretty nor fast.

Another approach would be to hand-craft (or generate using T4-templates) those proxies. Manual coding means a lot of maintenance effort. Templates would still involve some interaction for regenerating the proxies when the interfaces change.

A solution that comes with the performance of hand-crafted and compiled code and the convenience of auto-generation by the container are proxies that are dynamically generated using Reflection.Emit.

A code generator creates classes that are wrappers around a Lazy<T> field and look something like this:

public class MyContract_LazyInstantiationProxy : IMyContract
{
  private Lazy<IMyContract> instance;
  public MyContract_LazyInstantiationProxy(Func<IMyContract> factory)
  {
    Guard.AssertNotNull(factory, "factory");
    this.instance = new Lazy<IMyContract>(factory);
  }
  public IMyContract Instance
  {
    get { return this.instance.Value; }
  }
  public string Foo(IBar bar)
  {
    return this.Instance.Foo(bar);
  }
}

And it’s really easy to configure using the provided extension method for IUnityContainer:

var container = new UnityContainer();
container.RegisterLazyProxy(
  x =>
    {
      x.Contract = typeof(IFooService);
      x.ServiceImplementation = typeof(FooService);
    });

Now you can just inject your service into the consumers and don’t have to care wether or not they are lazily instantiated. No leaky abstraction, no factory overload. Just plain constructor injection. Nice!

Grab the source code for the proxy generation here (project TecX.Unity folder Proxies and the test suite that shows how to use it in TecX.Unity.Proxies.Test).