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: , ,

Comments

Steve says:

Excellent description. Your Matrix analogy is good one as well 🙂

Cesar Sanz says:

Matrix analogy?? You are a genius!!!