Category: DynamicProxy

Castle Dynamic Proxy tutorial part II: The what, why and how

This is part two of my tutorial on Castle Dynamic Proxy.

If you’re new to it, you might want to read part 1 as well, although if you’re new to the concepts behind dynamic proxy, you may actually want to read this part first, as it outlines the what, why and how of dynamic proxy.

After I re-read my initial post, I realized that I didn’t actually provide proper introduction in it. I mean, I made an introduction to the sample project we’re creating along this series, but I feel I should have provided more explanation for people who aren’t familiar with it in some way already. What dynamic proxy is and why you might need it, instead of jumping into the code right ahead.

So this post is my way of stepping back a little, and explaining these concepts.

First, what the Dynamic Proxy is all about and why should you care? The Dynamic Proxy (DP for short) is, as its name implies a framework that helps you implement the proxy object design pattern. That’s the proxy part. The dynamic part, means that the actual creation of proxy type happens at runtime, and you dynamically can compose your proxy objects.

According to Wikipedia:

A proxy, in its most general form, is a class functioning as an interface to another thing. The other thing could be anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.

One way of thinking about proxies, is by the analogy to The Matrix.

I assume there’s no one on the planet who hasn’t seen the movie and can be spoiled here, by the details of the plot. Anyway, people in the matrix aren’t the actual people (“The spoon does not exist”, remember?) They’re proxies to the actual people that can be… wherever. They look like ones, they behave like ones, but at the same time, they are not them actually. Another implication is the fact that different rules apply to proxies. Proxies can be what the proxied objects are, but they can be more (flying, running away from bullets, that kind of stuff). Hopefully you get the point, before I take that analogy too far. One more important thing, is that proxies ultimately delegate the behavior to the actual objects behind them (kind of like – “if you’re killed in the matrix, you die in the real life as well”).

The good example of a transparent proxy from programmers daily work are WCF proxies. From the perspective of the code that uses them, they’re just some objects that implement an interface. They can use it, via the interface just like any other object, even though the actual implementation of the interface they’re using, may be on another machine.

This is an example of a proxy, that hides the location of the actual object, from its users, and it’s one way you can use proxies.

Another way, and it’s how DP is used mostly, is by adding behavior to the proxied objects.

That’s what we did with the IInterceptor classes in the part 1. We used them to inject behavior into the proxy.

dptutorial_2_proxy_schemat

The picture above shows schematically how that works. The blue rectangle is the proxy. Someone calls a method on the proxy (denoted by yellow arrow).

Before the method reaches the target object it goes through a pipeline of interceptors. Each interceptor gets a IInvocation object, that holds all the information about current request, like the MethodInfo of the method called, along with its parameters and returned value, reference to the proxy, as well as proxied object, and few others. Each interceptor gets its chance to inspect and change those values before the actual method on the target object is called. So for example at this stage you can log debug information about what parameters were passed to the method, or validate them.Then, the interceptor has to call invocation.Proceed(), to pass control further down the pipeline. An interceptor can call Proceed at most once, otherwise an exception is thrown.

After last interceptor calls Proceed, the actual method on proxied object is invoked, and then the call travels back, up the pipeline (green arrow) giving each interceptor chance to inspect and act on, returned value, or thrown exceptions. Finally the proxy returns the value held by invocation.ReturnValue as the return value of called method.

If this was not clear enough, here’s sample interceptor, that shows how it works:

[Serializable]
public class Interceptor : IInterceptor
{
	public void Intercept(IInvocation invocation)
	{
		Console.WriteLine("Before target call");
		invocation.Proceed();
		Console.WriteLine("After target call");
	}
}

Hopefully, at this stage you have a pretty good idea about what dynamic proxy is, how it works, and what it’s good for. In the next part we’ll dive into some more advanced capabilities, plugging into, and influencing the process of generating proxy class.

Technorati Tags: , ,

Castle DynamicProxy tutorial part I: Introduction and ProxyGenerator

I’ve been experimenting lately quite a lot with Castle Dynamic Proxy, creating prototype for a project I’m working on at work and I even implemented a small feature that was missing from it. Generally, Dynamic Proxy (DP from now on) is a great, lightweight framework, but it’s greatest downside is lack of documentation. It’s surprisingly logical and easy to use, but since there are almost no resources on the web that could help you get started with it, I decided to give it a go, and start a small tutorial series of posts, that will introduce various features of DP while working on a simple sample project.

The project is to build the ability to freeze objects, so that from the point in time where object has been frozen, its state cannot change. AFAIK there’s a similar feature in WPF, but since my knowledge of WPF is very limited, I don’t know how that works. The project itself is not important (nor the usefulness of its implementation). It’s only purpose is to serve as an excuse to explore various DP features. I am also aware that the state of the project shown here is far from what good code should look like. We will evolve the implementation in future parts of the tutorial, as we introduce other concepts and features of DP.

Basically here’s what we want to achieve:

  • Be able to use non-frozen freezable object just like any other object
  • Be able to check if the object is freezable
  • Be able to check if the object is frozen
  • be able to freeze freezable object
  • NOT be able to change state of the object after it has been frozen

How do we do that? DP creates a transparent proxy for the real object at runtime for us, and we can intercept the calls to it, and add logic to the objects. This is a very powerful capability.

To specify our requirements, we use tests, using xUnit framework:

[Fact]
public void IsFreezable_should_be_false_for_objects_created_with_ctor()
{
    var nonFreezablePet = new Pet();
    Assert.False(Freezable.IsFreezable(nonFreezablePet));
}

[Fact]
public void IsFreezable_should_be_true_for_objects_created_with_MakeFreezable()
{
    var freezablePet = Freezable.MakeFreezable<Pet>();
    Assert.True(Freezable.IsFreezable(freezablePet));
}

[Fact]
public void Freezable_should_work_normally()
{
    var pet = Freezable.MakeFreezable<Pet>();
    pet.Age = 3;
    pet.Deceased = true;
    pet.Name = "Rex";
    pet.Age += pet.Name.Length;
    Assert.NotNull(pet.ToString());
}

[Fact]
public void Frozen_object_should_throw_ObjectFrozenException_when_trying_to_set_a_property()
{
    var pet = Freezable.MakeFreezable<Pet>();
    pet.Age = 3;

    Freezable.Freeze(pet);

    Assert.Throws<ObjectFrozenException>(() => pet.Name = "This should throw");
}

[Fact]
public void Frozen_object_should_not_throw_when_trying_to_read_it()
{
    var pet = Freezable.MakeFreezable<Pet>();
    pet.Age = 3;

    Freezable.Freeze(pet);

    var age = pet.Age;
    var name = pet.Name;
    var deceased = pet.Deceased;
    var str = pet.ToString();
}

[Fact]
public void Freeze_nonFreezable_object_should_throw_NotFreezableObjectException()
{
    var rex = new Pet();
    Assert.Throws<NotFreezableObjectException>(() => Freezable.Freeze(rex));
}

We use static class Freezable to create freezable objects, and to query their state. This allows us to have really simple API (and implementation), and encapsulate all (well, not all – yet) freezable logic in one place. This implementation has one shortcoming that you may have spotted – the class we want to make freezable instance of, has to have a default, parameterless constructor.

This is not a DP limitation however, and further along the way, we will remove it.

The way DP works, is by subclassing given class and overriding its methods. This approach has a few limitations:

  • you obviously can’t proxy a sealed class, since it can’t be inherited from
  • you can only override virtual methods, so for non-virtual methods there’s nothing you can gain

Ok, so how do we go about implementing the whole thing?

First we need some way of tracking which objects are freezable and their freezability state. For that we create an interface:

internal interface IFreezable
{
    bool IsFrozen { get; }
    void Freeze();
}

It will help us by providing all the information and functionality we need.

Then, in our Freezable static class we create a dictionary, that will map objects, to their freezability state:

private static readonly IDictionary<object, IFreezable> InstanceMap = new Dictionary<object, IFreezable>();

With that, implementation of Freezable methods should be really straightforward:

public static bool IsFreezable(object obj)
{
    return obj != null && InstanceMap.ContainsKey(obj);
}
 
 
public static void Freeze(object freezable)
{
    if (!IsFreezable(freezable))
    {
        throw new NotFreezableObjectException(freezable);
    }

    InstanceMap[freezable].Freeze();
}
 
public static bool IsFrozen(object freezable)
{
    return IsFreezable(freezable) && InstanceMap[freezable].IsFrozen;
}

Still however, no word about DP, and the implementation of MakeFreezable is missing. Also, a reader may point out, that by virtue of keeping some mapping from objects to interface, objects won’t magically gain behaviour.

That is true, with a little bit of work however, they will.

What we need to do, is to monitor calls to property setters, and if object is indeed frozen calling a setter should raise an exception, as shown in the test. To do that we need to actually intercept the call, and for that, we have the IInterceptor interface.

IInterceptor has only one method:

Castle.Core.Interceptor.IInterceptor.Intercept(Castle.Core.Interceptor.IInvocation);

The IInvocation is another interface that holds all the information about the call.

dptutorial_1_iinvocation

We can query its Method property to get MethodInfo object pointing to the called method, Proceed method, that invokes the method on target object and few other methods and properties that we will examine in future parts of the tutorial. With that, we have all we need to actually implement our freezable logic:

internal class FreezableInterceptor : IInterceptor, IFreezable
{
    public void Freeze()
    {
        IsFrozen = true;
    }

    public bool IsFrozen { get; private set; }

    public void Intercept(IInvocation invocation)
    {
        if (IsFrozen && IsSetter(invocation.Method))
        {
            throw new ObjectFrozenException();
        }

        invocation.Proceed();
    }

    private static bool IsSetter(MethodInfo method)
    {
        return method.IsSpecialName && method.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase);
    }
}

Our interceptor holds the freezability state of the object. Since we create one interceptor per object, it will work. In the Intercept method, interceptor checks if the object is frozen, and if called method is a property setter. If indeed that’s the case, it means that we’re trying to set a property of a frozen object, so an ObjectFrozenException is thrown. Otherwise, we can proceed with the call.

Now, it’s really easy to implement Freezable.MakeFreezable method. We know how to intercept calls. The only piece missing is – how do we actually create the proxies. For that, we use the ProxyGenerator class. We only need one instance, so we may keep it as a static field in the Freezable class

private static readonly ProxyGenerator Generator = new ProxyGenerator();

ProxyGenerator class is the heart of the DP library. It has numerous methods for creating different kinds of proxies, but for now, we will only use one: CreateClassProxy, that creates a proxy for a class.

public static TFreezable MakeFreezable<TFreezable>() where TFreezable : class, new()
{
    var freezableInterceptor = new FreezableInterceptor();
    var proxy = Generator.CreateClassProxy<TFreezable>(new CallLoggingInterceptor(), freezableInterceptor);
    InstanceMap.Add(proxy, freezableInterceptor);
    return proxy;
}

We create a FreezableInterceptor to intercept the calls, verify freezability state of the connected object, and throw if necessary, then we create the actual proxy, add it along with its FreezableInterceptor to the dictionary, and return.

In call to CreateClassProxy generic method we pass one more argument – a new instance of CallLoggingInterceptor. It’s a simple class that also implements IInterceptor interface that logs all the intercepted calls to the console. This also means that you can have more than one interceptor for a proxy which is a very powerful and handy capability.

With that, we basically have our initial implementation complete, we only need to create missing exception classes and we are good to go. Indeed, all the tests should pass now.

dptutorial_1_tests_pass

We can create sample console application to see how that works:

class Program
{
    static void Main()
    {
        var rex = Freezable.MakeFreezable<Pet>();
        rex.Name = "Rex";
        Console.WriteLine(Freezable.IsFreezable(rex)
            ? "Rex is freezable!"
            : "Rex is not freezable. Something is not working");
        Console.WriteLine(rex.ToString());
        Console.WriteLine("Add 50 years");
        rex.Age += 50;
        Console.WriteLine("Age: {0}", rex.Age);
        rex.Deceased = true;

        Console.WriteLine("Deceased: {0}", rex.Deceased);
        Freezable.Freeze(rex);
        try
        {
            rex.Age++;
        }
        catch (ObjectFrozenException)
        {
            Console.WriteLine("Oops. it's frozen. Can't change that anymore");
        }

        Console.WriteLine("--- press enter to close");
        Console.ReadLine();
    }
}
 
public class Pet
{
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
    public virtual bool Deceased { get; set; }

    public override string ToString()
    {
        return $"Name: {Name}, Age: {Age}, Deceased: {Deceased}";
    }
}

The output of the application looks like this:

dptutorial_1_app

Bam! We get the behavior we wanted, without actually modifying the Pet class, and with surprisingly few lines of code. It may be a little bit overwhelming right now, but what we did, boils down to three things:

  1. We created an IInterceptor implementation, that overrides Intercept method and keeps track of freezable state of an object.
  2. We created a proxy object with ProxyGenerator.CreateClassProxy method
  3. We created really simple logic to correlate out freezable objects with interceptors, that keep their state.

And with all of that we barely scratched the surface of what can be done with DynamicProxy.

As a bonus, if you are curious how the proxy type generated by DP looks like, here’s what Reflector shows:

dptutorial_1_reflector

If the last screenshot left you with headache don’t worry, by the end of this tutorial it will be all crystal clear.

See you in part II, where we will introduce IProxyGenerationHook, to give us more fine-grained control over our interceptors.

If you have any questions or suggestions please, leave a comment.

The solution with tests is available here.

To run tests, you will also need xUnit framework, available here.