Infos

Sie befinden sich in den Archiven der Kategorie DynamicProxy.

Februar 2012
M D M D F S S
« Jun    
 12345
6789101112
13141516171819
20212223242526
272829  
Kategorien
Archive

Archiv der Kategorie DynamicProxy

Using Proxies: Proxies using Castle.DynamicProxy2

At the end of the last blog I mentioned, that it is not useful to write proxies by hand. The reason
for this is very clear…many unnecessary work, error-prone, not easy to maintain if it comes to
changes in the interface etc. Therefore it would be nice, if we could automate that process.

The Castle project contains a library called DynamicProxy. As the name says, the aim of this
library is to provide functionality to create dynamic proxies at runtime. The problem is that the
documentation for this is not very complete and examples are rare or do not fit the needs
for beginners. Therefore I want to write here what I’ve learned so far. For this we’ll stick to the
simple ITask example from the last blog.

So, let’s have a look, how this could be helpful, to avoid hand written proxies. The first question
that arises is, how can a proxy be constructed at runtime?  This is done by using the classes
provided by the System.CodeDom and System.Reflection namespaces of the .net framework.
We’ll leave it to this, since the details of the implementation aren’t really interesting, when using
the library. The only interesting thing right now is, that we can build an proxy object for any
existing class. This is done with the

proxy_generator.jpg

class. But before we go further, there is one big thing to think about. In the TaskProxy from
the last blog, we have implemented our own version of the doExecute() method, where we
checked, if a user is allowed to execute a task or not. If we now have a dynamicly constructed
proxy, generated by the ProxyGenerator, how can we provide our own implementation for it?
There must be a way to step in the execution process of the method. Without this possibility
everything else makes no sense. So thats why the methods from the ProxyGenerator want
some additional parameters:

proxy_creatinterface_param2.jpg

We have to provide one (or more) objects that implements the IInterceptor interface.  This
interface is defined in the Castle.Core.Interceptor namespace and is exactly what we are
looking for, because this is the place, where our own proxy implementation lifes. To achieve
this, we only have to implement one single method:

 proxy_interceptor.jpg

As parameter an IInvocation - object is provided. This gives us some importand informations
about the current execution. Since we don’t override a specific method, we have to know wich
method is currently executed and what parameters are stated to the call. Furthermore we need
access to the real TaskImpl object and maybe have to set return values etc. All this could be
done using the invocation properties. The definition looks like this:

proxy_invocation.jpg

Beside this we can see a call to a Proceed() method. With this call we simply allow the proxy to
continue the actual called method.

We can run our test from the last blog now. Let’s stop after the proxy was generated. We can see
the following result:

proxy_class_proxy1.jpg

As we can notice, the returned object is a randomly generated typename for the proxy.
Let’s make another breakpoint at the Intercept method. What happens?
To our disappointment nothing really happens :-( So what’s wrong here? The answer to this is
simple. As mentioned above, the proxy is generated using System.CodeDom. That means a new
type is build in memory with implementations for all methods and properties of the base class,
wich is TaskImpl in our case. The so created proxy class inherits from TaskImpl and tries
to override the methods to allow interception. Doing this, the same rules are effective as when
we would do this by hand.  This means to override a method in an inherited class, the method
has to be virtual in the base class. So let’s change our TaskImpl class and try it again:

 proxy_interceptor2.jpg

That’s better. The call to invocation.Proceed() now simply continues the doExecute()
method of our TaskImpl class. Putting it all together, we can now implement our proxy
behaviour, as we did in the last blog:

proxy_interceptor_final1.jpg

The TaskProxy is no longer needed and our tests run succesfully:

 proxy_interceptor_test1.jpg

In the end this is a quick overview of how to use DynamicProxies. There is a lot more to
talk about, but I think it is agood starting point for using the library and to understand, how
proxies are generated and what one can do with it.

To see exactly what happens behind the scene, you can make the proxy persistent and have
a look at it using .NET Reflector. To do this, simply call:

 proxy_persistent.jpg

Now open the resulting assembly in the .NET Reflector. Here you can see the generated class
for the proxy and what is done to the doExecute() method.

proxy_reflector.jpg