AOP

Over the last eighteen months or so I’ve developed a couple of applications that make heavy use of messaging and queues and found myself having to think about the implications of asynchronous, out of process code, something that ordinarily most of us don’t even consider. We’re naturally inclined to think about everything as request and response, and whenever a remote call is required we immediately reach inside our web services toolkit and bring out WCF or even asmx. With messaging you have to, to quote a fruit-based computer company, “think differently”. The good thing for me was that these projects brought certain ideas more clearly into focus giving me a whole new perspective.

During that time (well, for a lot longer actually) I’ve absorbed whatever I could find from Greg Young and Udi Dahan, be it blog posts or videos (hurry up with the book, Greg!). These two people are the guys that have probably influenced me the most, especially when it comes to CQRS and architecture. It’s their knowledge (and Greg’s focus on “messages” in particular) that has continuously kept me challenging my own assumptions and together with the experience I’ve gained from those messaging projects I feel like another piece of the puzzle has slowly but surely dropped into place. In fact it feels like that moment when I felt the object oriented lightbulb switch on after years of procedural programming, only, thanks to this new step forward, I now realize that the OOP moment wasn’t quite the epiphany I thought it was.

The thing about messaging and the patterns around it is that they are not just for distributed systems. Messaging concepts have a place within ordinary applications and I’d go as far as to say that, actually, the idea of the message as an explicit concept in your code is a key component of good object oriented software, one that was originally pushed by the pioneers but has somehow been diluted over the years. I’m pretty sure that this is exactly the idea the that Greg Young in particular has been trying to get across to developers for some time now. Go back and watch some of the videos on Skillsmatter such as Assert.That(We.Understand) where he talks about incredibly rich tests that you could give to a business person and they would see a specification written entirely in English, generated out of a command (message) that ultimately became an event (another message) that he could then use to build that business-friendly output.

He also talks about this concept of passing messages around in a video from Oredev a few years ago called 19 1/2 Things To Make You A Better Object Oriented Programmer. You can find it here, go watch it, it’s another excellent talk.

Once you have an explicit concept defined in your system as a message you can actually do some interesting stuff in your code. As an example, one of the patterns well known in the distributed messaging world is the pipe and filters pattern. This pattern allows for the transformation of a message through a series of filters (message handlers) as it passes from queue to queue over the transport mechanism (pipe) until it reaches it’s final destination at which point the message may well look very different from how it started out. This same technique is easy to do in an application by creating a set of classes that act as the filters for the particular message type. These are chained together so that when the first filter has finished transforming the message in some way its output becomes the input of the next filter and so on. Using this technique I was able to refactor an application that had some quite horrible to read code for basically doing nothing more than importing an excel spreadsheet into a database as a batch job. There were a number of complicated steps along the way that taken together made for one ugly path through the code because there didn’t seem to be a nice way to structure it. However, breaking these steps out into classes, each responsible for doing their bit on the message (the Excel dataset) and then passing it on to the next made a dramatic difference to the readability of the code. Not only that, new steps could also be plugged in at any point in the chain without affecting the other code.

This should feel like nothing new, after all, we all know the benefits of OOP and the principles surrounding it such as SRP, Open/Closed, etc but for all that we still end up working on codebases that seem to completely ignore them. And now I think I know why – messages.

Messages are the concepts that really allow us to unlock the benefits of object oriented languages. We need to cut down on passing around the primitive types and instead think at a higher level of abstraction, i.e. in terms of messaging.

As another example, you can pass a command message to your application and push it through an in-memory bus so that the correct handler is invoked, again because you’ve defined an explcit message. Just imagine how much cleaner your MVC controllers would look by just doing Bus.Send(msg) and having it routed to a handler that acts on it. That same handler could be wrapped with other handlers that “intercept” the message to do cross cutting concerns such as logging, transactions, security, etc. Your controller would neither know nor care. Once again, possible because you made a concept explicit. This is also evident in CQRS in that messages come in as commands, are handled in a way that invoke behaviour on domain objects which then end up generating events that eventually make their way out to event handlers.

This focus on explicit messages has affected the way I write software. I tend to focus much more on behaviour and my code feels cleaner and easier to read because of it. Extension points tend to occur naturally because messages tease out a more object oriented solution. They also make keeping the bigger picture of the software in your head a little bit easier too because instead of thinking about methods and passing primitives around, you can now visualize the flow of a message as it passes through the various parts of your system.

I love those all too rare moments when you see things from a new perspective. I’d heard Greg Young talk about these things long before I grasped the real meaning, always thinking, yeah I’m doing that, etc but never really knowing if I’d understood correctly but at last the light is shining. I think it took the actual experience of working on a distributed message queing system for me to see things in that new light. All of a sudden things clicked and made me want to revisit old code to see if what I had learned could be applied, and of course, I found it could. Messages are such an important concept, distributed or not, that I now wonder why more hasn’t been made of the idea by various authors, practitioners, etc. over the years. Maybe they have and I just didn’t grok it or maybe they haven’t had their lightbulb moment yet? Whatever the reason I think messaging should be given proper consideration as a central component of any moderately complex project. The benefits are many with, as far as I have experienced, few drawbacks, the main one being the required shift in perspective but the effort is worth it.

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:

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:

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:

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:

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.