AOP With Castle Windsor

Aspect Oriented Programming is a technique that in my opinion all developers should at least be aware of yet in my experience most that I have spoken with have not heard of it let alone used it. Maybe it gets glossed over because it seems like an alternative to OOP rather than complimenting it? Or perhaps it looks a little bit complex or hard to see where it could be useful? I don’t know but I do know it can greatly simplify a codebase by separating the business logic from the cross cutting concerns. But what’s a cross cutting concern?

Most developers, even if not familiar with AOP, at least understand cross-cutting concerns. Logging is the traditional example. It’s generic code that every app needs and it doesn’t belong to one particular layer but is used in many different layers. It’s also code that we seem to duplicate over and over in method after method. It becomes tedious to write, a chore to maintain, and it gets in the way of the real intent of the method the reader is currently focused on. It’s also a prime candidate for AOP.

Other examples include transaction management and authorisation. Every time we communicate with our data layer we need to begin a transaction, call our data method then commit or rollback. AOP can help us here as it can with authorisation. Instead of tediously writing the same code to check that the current user is authorised to call the method we can use aspects to do the work for us.

So the next question is, what is an aspect?

Aspects are units of code that can be applied to other parts of our codebase in a non-intrusive manner. They give us the ability to write code once but have it applied in many places. The code that the aspect affects becomes a lot simpler as the “noise” has been moved to a more suitable place. Both the code and the aspect gain a clear separation of concerns. The aspect concentrates on providing the cross cutting concern whilst the method it affects concentrates on the business logic.

AOP has a couple of different flavours, IL code weaving being one (see PostSharp for this method and also a nice video presentation here) and interception which is the method used by Castle Windsor and what I’m going to show here. IL code weaving is a post-compilation process where by the IL code is altered to have the aspects “weaved” into the dll. It has potential for more powerful use cases than interception which is applied dynamically but often interception can give us a great deal and Castle Windsor makes it easy.

When creating our own aspects we need to implement a single interface – IInterceptor. My own convention is to name my classes with a post-fix of Aspect so that anyone reading my code would immediately recognise the concept. So let’s take the Logging example:

public class LoggingAspect : IInterceptor
{
      public void Intercept(IInvocation invocation)
      {
            invocation.Proceed();
      }
}

Here we’ve created a class that will (but doesn’t yet) do some logging for us. We’ve implemented the IInterceptor interface and so done the minimum possible to compile. The IInvocation variable represents the method that does the real work i.e implements our business logic. Calling the Proceed method invokes it. We can do logging before or after our method is called depending on our needs. So if, for instance, we use Log4Net as our logging tool of choice we’d end up with something like this:

public class LoggingAspect : IInterceptor
{
      public void Intercept(IInvocation invocation)
      {
            Log.Debug(string.Format("Entered: {0}", invocation.Method.Name));
            invocation.Proceed();
            Log.Debug(string.Format("Exited: {0}", invocation.Method.Name));
      }
}

If our business logic method returns a result we can also use this in our aspect:

public class LoggingAspect : IInterceptor
{
      public void Intercept(IInvocation invocation)
      {
            Log.Debug(string.Format("Entered: {0}", invocation.Method.Name));
            invocation.Proceed();
            Log.Debug(string.Format("Exited: {0} with return value of {1}",
            invocation.Method.Name,
            invocation.ReturnValue);
      }
}

The transaction example is pretty simple:

public class TransactionAspect : IInterceptor
{
      public void Intercept(IInvocation invocation)
      {
            using(var scope = new TransactionScope())
            {
                  invocation.Proceed();
                  scope.Complete();
            }
      }
}

All we’ve done here is wrap a TransactionScope object around the call to invocation.Proceed. If that method throws an exception then the scope.Complete() call never happens and our changes are rolled back upon exiting the using block.

The final example, Authorisation, shows how we can make a decision on whether or not the current logged in user is allowed to call our method:

public class AuthorisationAspect : IInterceptor
{
      public void Intercept(IInvocation invocation)
      {
            var currentUser = System.Threading.Thread.CurrentPrincipal;
            if(currentUser.Identity.IsAuthenticated && currentUser.IsInRole("admin"))
                  invocation.Proceed();
            else
                  throw new UnauthorizedAccessException("For admin eyes only!");
      }
}

Once we’ve written our aspects we need to register them in our IoC container:

_container = new WindsorContainer();

// register the aspects
_container.Register(AllTypes.FromAssembly(Assembly.LoadFrom("mytypes.dll"))
      .Pick().If(t => t.Name.EndsWith("Aspect")));

// register the types we want aspects applied to
_container.Register(AllTypes.FromAssembly(Assembly.LoadFrom("mytypes.dll"))
      .Pick().If(t => t.Name.EndsWith("Command"))
      .Configure(c => c.LifeStyle.Transient
      .Interceptors(new[] { typeof(LoggingAspect) })));

Here we’re applying aspects only to objects whose name end with the word Command. Every command object in the container will be decorated with the LoggingAspect. Alternatively, you can use attributes to selectively apply Aspects to your objects. This example ensures that only admins (based on the AuthorisationAspect defined above) can execute this command:

[Interceptor(typeof(AuthorisationAspect))]
public class DeleteAllDataCommand : ICommand
{
      public virtual void Execute()
      {
            // delete everything!!
      }
}

Now whenever we resolve a component from the container the object returned has the appropriate aspects automatically ‘wrapped” around it and any call to the component’s methods are “intercepted” so that the aspects code runs before and after the invocation.

There are potentially a lot of uses for Aspects which due to their non-invasive nature make the important code of our application a lot simpler to maintain and easier on the eye too. The drawback is that it isn’t immediately obvious what other code runs when we invoke our method but in my opinion this is far outweighed by the benefits. As usual though, just because we can doesn’t mean we always should but adding AOP to your developer toolbox is definitely worthwhile as it gives you another option to consider when faced with the cross cutting concern problem.

AOP With Castle Windsor