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

This is part two of my tuto­r­ial on Cas­tle Dynamic Proxy.

If you’re new to it, you might want to read part 1 as well, although if you’re new to the con­cepts behind dynamic proxy, you may actu­ally want to read this part first, as it out­lines the what, why and how of dynamic proxy.

After I re-read my ini­tial post, I real­ized that I didn’t actu­ally pro­vide proper intro­duc­tion in it. I mean, I made an intro­duc­tion to the sam­ple project we’re cre­at­ing along this series, but I feel I should have pro­vided more expla­na­tion for peo­ple who aren’t famil­iar with it in some way already. What dynamic proxy is and why you might need it, instead of jump­ing into the code right ahead.

So this post is my way of step­ping back a lit­tle, and explain­ing 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 frame­work that helps you imple­ment the proxy object design pat­tern. That’s the proxy part. The dynamic part, means that the actual cre­ation of proxy type hap­pens at run­time, and you dynam­i­cally can com­pose your proxy objects.

Accord­ing to Wikipedia:

A proxy, in its most gen­eral form, is a class func­tion­ing as an inter­face to another thing. The other thing could be any­thing: a net­work con­nec­tion, a large object in mem­ory, a file, or some other resource that is expen­sive or impos­si­ble to duplicate.

One way of think­ing about prox­ies, is by the anal­ogy 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. Any­way, peo­ple in the matrix aren’t the actual peo­ple (“The spoon does not exist”, remem­ber?) They’re prox­ies to the actual peo­ple that can be… wher­ever. They look like ones, they behave like ones, but at the same time, they are not them actu­ally. Another impli­ca­tion is the fact that dif­fer­ent rules apply to prox­ies. Prox­ies can be what the prox­ied objects are, but they can be more (fly­ing, run­ning away from bul­lets, that kind of stuff). Hope­fully you get the point, before I take that anal­ogy too far. One more impor­tant thing, is that prox­ies ulti­mately del­e­gate the behav­ior 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 exam­ple of a trans­par­ent proxy from pro­gram­mers daily work are WCF prox­ies. From the per­spec­tive of the code that uses them, they’re just some objects that imple­ment an inter­face. They can use it, via the inter­face just like any other object, even though the actual imple­men­ta­tion of the inter­face they’re using, may be on another machine.

This is an exam­ple of a proxy, that hides the loca­tion 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 behav­ior to the prox­ied objects.

That’s what we did with the IIn­ter­cep­tor classes in the part 1. We used them to inject behav­ior into the proxy.

dptutorial_2_proxy_schemat

The pic­ture above shows schemat­i­cally how that works. The blue rec­tan­gle is the proxy. Some­one calls a method on the proxy (denoted by yel­low arrow).

Before the method reaches the tar­get object it goes through a pipeline of inter­cep­tors. Each inter­cep­tor gets a IIn­vo­ca­tion object, that holds all the infor­ma­tion about cur­rent request, like the Method­Info of the method called, along with its para­me­ters and returned value, ref­er­ence to the proxy, as well as prox­ied object, and few oth­ers. Each inter­cep­tor gets its chance to inspect and change those val­ues before the actual method on the tar­get object is called. So for exam­ple at this stage you can log debug infor­ma­tion about what para­me­ters were passed to the method, or val­i­date them.Then, the inter­cep­tor has to call invocation.Proceed(), to pass con­trol fur­ther down the pipeline. An inter­cep­tor can call Pro­ceed at most once, oth­er­wise an excep­tion is thrown.

After last inter­cep­tor calls Pro­ceed, the actual method on prox­ied object is invoked, and then the call trav­els back, up the pipeline (green arrow) giv­ing each inter­cep­tor chance to inspect and act on, returned value, or thrown excep­tions. 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 sam­ple inter­cep­tor, 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");
	}
}

Hope­fully, 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 capa­bil­i­ties, plug­ging into, and influ­enc­ing the process of gen­er­at­ing proxy class.

Tech­no­rati Tags: , ,
  • http://blogger.forgottenskies.com/ Steve

    Excel­lent descrip­tion. Your Matrix anal­ogy is good one as well :)

  • Cesar Sanz

    Matrix anal­ogy?? You are a genius!!!