Dynamic Proxies with Castle.DynamicProxy

I’ve recently had to look at updating our very old version of The Castle.DynamicProxy to a more recent version and things have changed a little, so I thought it’d be a perfect excuse to write a little blog post about dynamic proxies and the Castle.DynamicProxy in particular.

What is a dynamic proxy?

Let’s begin with a simple definition – a proxy acts as an interception mechanism to a class (or interface), in a transparent way and can allow the developer to intercept calls to the original class and add or change functionality on the original class. For example, NHibernate uses them for lazy loading and mocking frameworks use them to intercept method/property calls.

Sounds great, what are the pitfuls?

The primary pitful of a dynamic proxy is that can added tot he overal memory footprint of your application if used too liberally. But if it supplies the functionality you require then this probably isn’t an issue, especially with 64-bit memory limits. Obviously they add an element of complexity which can become a pain to debug through, ofcourse there’s always trade offs.

Let’s see some code

We’re going to use the Castle.Core nuget package for this example, so create yourself a Console application, add this package to your references and then we’re good to go.

Proxies in remoting require you to derive your class from MarshalByRefObject, but this is not practical if you are unable to change the base class of your class. With Castle.DynamicProxy we can proxy our class without changing the base class, although we will need the class members to be virtual to use this code.

We’re going to create an interceptor which, as the name suggests will be used to intercept calls to our object by the dynamic proxy and in this case we’ll log to Console the method/property called.

public class Interceptor : IInterceptor
{
   public void Intercept(IInvocation invocation)
   {
      Console.WriteLine($"Before target call {invocation.Method.Name}" );
      try
      {
         invocation.Proceed();
      }
      catch (Exception e)
      {
         Console.WriteLine($"Target exception {ex.Message}");
         throw;
      }
      finally
      {
         Console.WriteLine($"After target call {invocation.Method.Name}");
      }
   }
}

Now let’s create a simple class to use to demo this, it’ll have both a method and property to get a flavour for how these should look

public class MyClass
{
   public virtual bool Flag { get; set; }

   public virtual void Execute()
   {
      Console.WriteLine("Execute method called");
   }
}

Simple enough – notice we need to mark these property and method as virtual, also notice we’ve done nothing else to the class to show it’s going to be used in a proxy scenario.

Finally let’s see the code to proxy this class and change the property and run the method

var proxy = new ProxyGenerator()
   .CreateClassProxy<MyClass>(
       new Interceptor());
proxy.Flag = true;
proxy.Execute();

That’s it. The output from running this in a Console will be

Before target call set_Flag
After target call set_Flag
Before target call Execute
Execute method called
After target call Execute

The Flag property setter is run, followed by the Execute method, both of which are intercepted.

We can also intercept interfaces (as you’d expect as dynamic proxies are used in mocking frameworks). However, your interceptor would need to mimic the functionality of an implementation of the interface. So for this example comment out the invocation.Proceed(); call in the interceptor.

Here’s a simple interface

public interface IPerson
{
   string FirstName { get; set; }
   string LastName { get; set; }
}

Now our code for executing our proxy against this interface would look like this

var proxy = new ProxyGenerator()
   .CreateInterfaceProxyWithoutTarget<IPerson>(
      new Interceptor());
proxy.FirstName = "Scooby";
proxy.LastName = "Doo";

The output will show the calls to the interface property setters. We can create a dynamic proxy to an interface but supply the underlying target by implementing the interface and supplying an instance to the proxy generator – so uncomment the invocation.Proceed(); line in the interceptor, implement the IPerson interface, such as

public class Person : IPerson
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

and now our proxy generator code can be change to this

var proxy = (IPerson)new ProxyGenerator()
   .CreateInterfaceProxyWithTarget(
      typeof(IPerson), 
      new Person(),
      new Interceptor());
proxy.FirstName = "Scooby";
proxy.LastName = "Doo";

in this example, we’ve not made our implementation properties virtual, and the Person setters will be invoked via the interceptor.

In this case the proxy is based upon the interface and simply calls the “target” object properties/methods. Hence this forwarding of calls means the target object does not need to have methods/properties marked as virtual.

A gotcha here is that all calls to the target must go through the proxy to be intercepted, this means that if your target call’s a method on itself, this will not be intercepted. To see this in action, let’s assume our IPerson now has a method void Change() and the implementation of this sets the FirstName to some value. So it looks like this

public void Change()
{
   FirstName = "Scrappy";
}

Now if you call the proxy Change method, it will be intercepted and our logging will be displayed but when it proceeds with the Change method (above), the the call to the FirstName setter will not be intercepted as this is run on the target not the proxy – hopefully that makes sense.