Dynamic Decorator and Castle DynamicProxy Comparison

Compare performance and features between Dynamic Decorator and Castle DynamicProxy

Editorial Note

This article appears in the Third Party Product Reviews section. Articles in this section are for the members only and must not be used by tool vendors to promote or advertise products in any way, shape or form. Please report any spam or advertising.

Introduction

Recently, I got a chance to play with Castle DynamicProxy a bit and did some comparisons between it and Dynamic Decorator. I found some interesting points and would like to share in this blog.

They are similar in that both use proxy concept. Both can be used to extend object functionality and add aspects to objects without modifying existing classes. The difference is that Dynamic Decorator overrides .NET's RealProxy and reuses its transparent proxy technology while Castle DynamicProxy uses a customized proxy technology. Your can find more information about them in the following links:

The CreateProxy method of the ObjectProxyFactory class in the Dynamic Decorator is mostly close to CreateInterfaceProxyWithTarget method of the ProxyGenerator class in the Castle DynamicProxy. The test is limited to use them to add some preprocessing functionality to an existing object.

Test Code

In this test, we try to add some logging functionality to an existing object. The following is the code for this test.

Performance

The first part of the code compares Castle DynamicProxy's performance with Dynamic Decorator's. In the above code, an object emp of class Employee is created. The first loop simply calls CreateInterfaceProxyWithTarget method of the ProxyGenerator class of the Castle DynamicProxy to create a proxy, then, uses the proxy to call the methods of the object emp for 1000 times. The second loop simply calls CreateProxy method of the ObjectProxyFactory class of the Dynamic Decorator, then, uses the proxy to call the methods of the object emp for 1000 times. The execution time of each loop is presented in the following table.

Castle DynamicProxy - First Loop

Dynamic Decorator - Second Loop

00:01:13.4976480

00:00:00.0781225

The Dynamic Decorator is orders of magnitude faster than the Castle DynamicProxy for doing exactly the same thing. Actually, the execution time for Dynamic Decorator is negligible. The Dynamic Decorator is clearly a winner in terms of performance.

Features

The following paragraphs discuss the feature differences between Dynamic Decorator and Castle DynamicProxy.

With Castle DynamicProxy, the preprocessing functionality is added to all methods of the object. There is no easy way to specify a particular method to decorate. It is either all methods or no methods to get the additional functionality. With Dynamic Decorator, however, individual methods can be specified. For instance, in the above code, we specify only the method DetailsByLevel when calling ObjectProxyFactory.CreateProxy of the Dynamic Decorator.

With Dynamic Decorator, you can access the method call context from within additional functionality. For example, in the above code, we are able to get the value of the parameter of the method DetailsByLevel. I am not aware of a way to do it in the Castle DynamicProxy.

From the above code, you see the proxy of the Dynamic Decorator can be chained. The variable emp originally references to the target object. And later, it references to the proxy of the target. You can keep doing this to create a chain of proxies each time adding some extra functionality.

The Dynamic Decorator has more features which can be used to enhance the preprocessing and postprocessing code.

Conclusion

The Dynamic Decorator is specifically designed to add additional functionality to objects. It is a lightweight and feature-rich tool to extend object functionality and to add aspects to objects. On the other hand, although the Castle DynamicProxy can be used to add aspects to objects, it suffers performance issue and has limited features to enhance the aspects.

Mobile development is not just another type of front end. The real challenge is actually in the back end: How to present meaningful information in time to mobile users with exponentially increased data flooding around? Here is my first mobile solution: SmartBars - Barcode Reader, Price Comparison and Coupons.

Gary lives in southeast Michigan. My first programming language is FORTRAN. For the last a few years, I have primarily focused on .NET technologies with Mobile Development as my newest interest.

Comments and Discussions

You're creating ProxyGenerator in each iteration! What's point in using IL-emit for a single call? Move creating of ProxyGenerator outside loop.
Also you're counting times of 2 methods via Castle and 1 methods via "Dynamic Decorator". It's unfair.
Also use Stopwatch for measuring.

Thank you for pointing out this. To be more fair, you should have also posted the time difference of creation between Dynamic Decorator and Castle DynamicProxy.

It is no surprise that a call using DynamiProxy is a little bit faster since it is injected code while a call using Dynamic Decorator are a method call. But in either case, they are negligible comparing to the creation time of the object.

As I said in the blog, I did some simple test. I'd appreciate that you could provide more thorough test cases to support your point.

"It is no surprise that a call using DynamiProxy is a little bit faster since it is injected code while a call using Dynamic Decorator are a method call. But in either case, they are negligible comparing to the creation time of the object"

Dear, Gary, as you can see in the modified sample I didn't remove creating proxed objects, I only removed creating of ProxyGenerator. It's the thing where all gererated code cached. You shouldn't create a ProxyGenerator's instance for an each proxied object.

BTW, the numbers you gave do not include object creation time. Does it mean no time is needed to create an object?

If possible, can you fill out the following questions using your correct data?

For Castle DynamicProxy:
1. How much time to create a Castle DynamicProxy proxy for target emp?
2. How much time to execute iemp.DetailsByLevel(2) uisng the Castle proxy?
3. The sum of the above 2.

For Dynamic Decorator:
1. How much time to create a Dynamic Decorator proxy object for target emp?
2. How much time to execution iemp.DetailsByLevel(2) uisng the Dynamic Decorator proxy?
3. The sum of the above 2.

If we cannot get onto the same page, we are wasting each other's time.

I basically allowed aspects to be defined through Attributes, and my proxy would look for these attributes and pass in the context (Method call). It did mean your objects were pretty neat and simply had a few extra attributes.

Like I say there were issues with Binding in WPF so I had to start using IL Weaving approach instead. Castles DynamicProxy did work for INPC but did not like certain other things, so had to abandon that too. IL Weaver seem logical next step.

To get the ObjectProxy work the way it is, I had to fool .NET remoting runtime twice.

First, in the constructor of ObjectProxy, the typeof(MarshalByRefObject) is passed into the base, i.e., RealProxy. It fools RealProxy that any type passed into the ObjectProxy is a remoting type.

Second, I had to implement the method CanCastTo of IRemotingTypeInfo to return true. It allows the transparent proxy to be cast to any interface type. The side effect of this is that if you cast the transparent proxy to a wrong type of interface, you will pass the compilatin but get a runtime error.

Read your article Bringing AOP to MEF and understood what you meant by "allowed aspects to be defined through Attributes".

Your article actually inspired me to come up with an idea to incorporate Aspect to MEF using Dynamic Decorator (see my article Configurable Aspects for MEF).

Here is the basic idea. You add customized entries in the configuration file to associate your business objects with the aspects. The customized MEF container brings objects in life and wires them with configured aspects.

This is not limited to the MEF, though. The other IoC containers (Unity and Windsor, etc.) should work similarly.

Thing is with the RealProxy approach, try it with something that uses DataBinding such as WPF/Silverlight and watch it fail with something like a INotifyPropertyChanged aspect. The Binding mechanism that WPF uses seems to not cause a INPC changes to fire as the object that you are proxyying does not fire these changes, even if you hook then up from the proxied object.

I also found things like custom ICommand object implmentation where I would use a Action and Func as the ICommand implementation would not be honored via the RealProxy approach.

I had to abandon the idea of using RealProxy and also Castles DynamicProxy. What I felt was needed was a pure IL weaving approach, so that is what I have ended up doing. Modify the type using custom MSBUILD task using Il magic.

Also I did not like the idea that using RealProxy I either had to use an interface or use MarshalByrefObject.

I'll try and remember to let you know when I post my article. I have just done it. Even the IL approach did not like custom ICommand object implmentation where I would use a Action and Func as the ICommand implementation

PS : One other thing I did not like using RealProxy was if you wanted to examine your object your had to drill into RealProxy properties quite a bit. In fact your implementation has this too. Try and stick a break point into your demo program of your previous article (case "1": //Add preprocessing and postprocessing aspects) and to figure out what the tpem object currently looks like you need to navigate the RealProxy as follows:

Raw View
-> Non Public Members
-> _rp
-> [NCT.ObjectProxy]
-> target

With Castle since they use Reflection.Emit, you see the object as it actually was