AOP is a neat trend that has been going on for awhile, but only recently have some tools been made (in .NET) to support it. But first, a definition:
In computing, aspect-oriented programming (AOP) is a programming paradigm in which secondary or supporting functions are isolated from the main program’s business logic. It aims to increase modularity by allowing the separation of cross-cutting concerns, forming a basis for aspect-oriented software development. Wikipedia
In plain english, it means you take out common tasks like logging or caching, and reduce them to a similar “aspect” that you can apply to your code more than once. This makes a lot more sense if you see it in action, so here we go.
Let’s look at a example tracing call:
1 2 3 4 5 6 7 8 9
As you can see, there’s only one line of actual “business logic” in that method, yet because of tracing requirements we end up with a 4-line method. Using Aspects, we can reduce this to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
And then reuse the code as easily as:
1 2 3 4 5
This is all done with a tool called Post Sharp (in .NET anyways). It works by post-processing compiled code to look for those attributes that we add to methods and classes, and inserting the code we create in those Aspect classes into the compiled code – so essentially the compiled code output is the same as our first example, but as far as we’re concerned it’s an entirely separate function we maintain separately. There’s also a few options on how the code is inserted, giving users extra flexibility. For example:
- OnMethodBoundary – Like our example above, this code will be inserted before and/or after the target method is called
- OnMethodInvocation – This code is executed before the method is executed, allowing the method call to be intercepted and overriden if necessary. Think of caching – you can check a in-memory cache for a method result instead of executing some SQL code
- OnException – Basically the same as having a Catch block around your method – except you don’t have to code it.
- OnFieldAccess – If you need to do something before someone gets or sets a property, use this aspect. Useful for lazy initialization
Now instead of wrapping your code in using statements, or manually checking caches, or copy-and-pasting the same catch block, or throwing exceptions on security errors in your methods, you can write an aspect once and reuse it, like [Tracing] or [Cached] or [LogException] or [RequiresModuleSecurity(123, SecurityLevel.Level1)]