Code Elegance

Windsor Container and Interceptors

Using Castle Windsor Container, the well-known IoC framework , is possible to add a little bit of AOP to our applications using the Interceptor facility which enables the interception to the calls of methods  of a class configured for it.

To understand how this can be done I’ll show you a example based on a Logger class.

Typically, in a standard application, the log operations are carried out making calls to a dedicated  library that writes the log information in a file or in a database. The calls have to be explicitly written in our code and this code has to be mixed with application code.

Using an Interceptor the calls to the logging library can be moved to another class dedicated to logging and our application can be written without worrying about log that will be added without touching the existing code.

Windsor Container has a Facility dedicated to method interception. Writing an interceptor means write a class that implements the IInterceptor interface:

public interface IInterceptor { void Intercept(IInvocation invocation); }

The interface has only one method (Intercept) that will be called by Windsor before the execution of the method intercepted.

A simple implementation of a Console Logger may result like the following:

public class Logger : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Start executing: {0}", invocation.Method.Name); invocation.Proceed(); Console.WriteLine("Execution completed: {0}", invocation.Method.Name); } }

The above implementation of Intercept Method writes a message on the console both before and after the execution of the method. The intercepted method is executed with the call to invocation.Proceed().

To enable the interception, the Logger must be registered in the configuration file, in the component section, so add:

<component id="logInterceptor" service="CodicePlastico.WindsorInterceptor.Logger, CodicePlastico.WindsorInterceptor" type="CodicePlastico.WindsorInterceptor.Logger, CodicePlastico.WindsorInterceptor" />

Now the interceptor is ready and can be used to intercept the calls on a type that we register. For this example we use this repository that manages the  Customer entity:

public class CustomerRepository : ICustomerRepository { public IList<Customer> Read() { Console.WriteLine("Load Customer from Db"); return null; } public void Save(Customer item) { Console.WriteLine("Save customer to Db"); } public void Delete(Customer item) { Console.WriteLine("Delete Customer"); } }

And this CustomerRepository must be registered as a component:

<component id="customerRepository" service="CodicePlastico.WindsorInterceptor.ICustomerRepository, CodicePlastico.WindsorInterceptor" type="CodicePlastico.WindsorInterceptor.CustomerRepository, CodicePlastico.WindsorInterceptor" />

The snippet above register a standard component and if we want to intercept the calls on CustomerRepository we should add a little bit more xml like this:

<component id="customerRepository" service="CodicePlastico.WindsorInterceptor.ICustomerRepository, CodicePlastico.WindsorInterceptor" type="CodicePlastico.WindsorInterceptor.CustomerRepository, CodicePlastico.WindsorInterceptor"> <interceptors> <interceptor>${logInterceptor}</interceptor> </interceptors> </component>

The interceptor element tell to Windsor that the component with Id logInterceptor is the interceptor for this customerRepository.

Doing this way, the following code:

IWindsorContainer container = new WindsorContainer( new XmlInterpreter("windsor.xml")); ICustomerRepository repo = container.Resolve<ICustomerRepository>(); repo.Read();

Will write the following output:

Start executing: Read Load Customer from Db Execution completed: Read

The beauty of the code showed above is that the aspect dedicated to logging is completely orthogonal to the application code and is configurable using the XML configuration file. 

You can download the full code here: http://www.codiceplastico.com/files/Codiceplastico.WindsorInterceptor.zip

If you don’t know anything about Windsor Container, here you can find a good tutorial written by Simone Busoli.

Posted in Emanuele DelBono | No comments

No comments yet. Be the first.

Leave a reply

Spam Protection by WP-SpamFree