Archive | December, 2009

Using Castle’s Dynamic Proxy

17 Dec

As a user of Rhino Mocks, Ninject and certain parts of the Castle Project, I found myself wondering what the Castle Project’s dynamic proxy was. I have since learned and love the idea of, dynamic proxies.

What does a dynamic proxy do

A dynamic proxy is a way of generating a subclass from a class or interface of which is generally a model. That subclass overrides every method that it can (make your methods virtual to allow to do it). This provides the ability to intercept calls to all methods on your class/interface because the sub-classed methods route requests to an interface which dictates whether a call can proceed. You could implement that functionality yourself, however you would need to cater for all method calls. The dynamic proxy provides one interceptor handler for all methods, and you can have many interceptors on one class.

Cross cutting concerns

One of the major benefits of using proxy objects is the ability to separate cross cutting concerns such as logging. Take the following diagram as an example. It shows how the logging interceptor which takes care of the logging can log calls made to the person object without the person object having a reference or knowing about the logging interceptor. The person object also doesn’t know about the dynamic proxy library.

DynamicProxyDiagram

An argument for separating out logging from our classes could be that we might want to turn logging on or off, or that we want to replace our logging library at a later date. Both of those scenarios could be catered for by having a logging class which is directly called by our Person object. The advantage of doing that could be minor performance gains, and the disadvantage of not using a proxy is that the person object would be polluted with unnecessary code. Ideally a class would have a single purpose, and logging would not conform to the purpose of the person business object in my opinion because logging is an environmental aspect regarding person as opposed to actually defining what a person is. A strong example of this is using a dynamic proxy to add permission based access to calls on third party libraries without modifying the external library.

Interceptors

The following code shows how a logging interceptor might look. It logs the method name of the method that is currently being accessed, then it allows the method request to proceed. Without invocation.proceed, the call would not proceed to the person object in the previous example, and would instead be consumed.

    public class LoggingInterceptor : IInterceptor

    {

        public void Intercept(IInvocation invocation)

        {

            Console.Write("Log: Method Called: "+ invocation.Method.Name);

            invocation.Proceed();

        }

    }

 

Boxing and Un-boxing proxies

To create a proxy you can do the following:

ProxyGenerator generator = new ProxyGenerator();

Person person = generator.CreateClassProxy<Person>(new LoggingInterceptor());

 

If you are developing in a situation where you have a network boundary and you need to send your business objects across a network you will probably want to shed your proxies and possibly recreate the proxies on the other side of the network boundary.

var proxyTarget = personProxyObject as IProxyTargetAccessor

var person = proxyTarget.DynProxyGetTarget() as Person;

 

More Information

Advertisements