AOP with PostSharp

March 30, 2011

Recently I listened to show #640 of .Net rocks on which Carl and Richard talk with Gael Fraiteur about PostSharp and AOP in general. In the past I heard about AOP (Aspect Oriented Programming), but it was in the context of AspectJ which is for Java, and in general it appeared to me more of an academic or esoteric thing rather than something I really like to try and even actually use it. But that show raised my interest in that subject a lot and so I took a look at the PostSharp website which contains very clear explanations and examples and finally I downloaded it and started to play with it. I’ll write more about it after I’ll play with it some more, but here’s a brief overview about AOP and PostSharp to begin with (or you can go directly to the PostSharp website yourself if you want, but here I’m trying to summarize it for you)

So what is AOP, and what the heck should I care?

As mentioned earlier, AOP stands for Aspect Oriented Programming. If this is the first time you hear this term it probably doesn’t tell you much either. So here’s the story: from one hand we want our code to be clean and maintainable, and that’s fine as long as we’re dealing only with pure business logic. But apart of the business logic, often you need some “plumbing” code or things that serve other needs other than the pure business logic, and is spread all over the place. For example, logging, thread synchronization, exception handling, caching, security, data-binding, and so on. These needs are often referred to as “Cross-cutting concerns”, because they are orthogonal to the business logic.

Due to these concerns, without AOP you’ll normally end up with code that is a mesh of business logic and these “horizontal” related code, which is obviously not very maintainable.

The conceptual solution for this, which is the philosophy behind AOP is Separation of Concerns. In fact, this concept also stands at the foundations of the OO approach as the encapsulation property of OO design (meaning that each class is concerned about only one responsibility, and is separated from the other classes by hiding its internal implementation). While OO does a good work in separating the concerns of different parts of the business logic, it doesn’t help much with the cross-cutting concerns, and this is where AOP comes in. In particular it means that you write your business logic as if it’s not aware of all the other concerns, and implement the Aspects (which are the implementations that deal with the cross-cutting concerns) in a way which is agnostic to the business logic and separated from it.

AOP technologies are said to “Weave” the aspects code into the normal (business logic) code. Generally AOP technologies are divided into 2 categories: Static AOP (which PostSharp belongs to) and Dynamic AOP. The key difference is whether the weaving takes place at compile (or build) time, or at run-time. There are pro’s and con’s to each of these approaches and I won’t get into more details about dynamic AOP here.

At a very high-level, this is how PostSharp works:

1. You write your aspect as a class that derives from one of the Attribute classes that are provided by PostSharp. For example:

   1: public sealed class TraceAttribute : OnMethodBoundaryAspect
   2: {
   3: }

2. Override the relevant methods of the base class. For example:

   1: public override void OnEntry(MethodExecutionArgs args) 
   2: { 
   3:     Trace.WriteLine(string.Format(“Entering {0}.{1}.”, 
   4:         args.Method.DeclaringType.Name, args.Method.Name), this.category); 
   5: }     
   7: public override void OnExit(MethodExecutionArgs args) 
   8: { 
   9:     Trace.WriteLine(string.Format(“Leaving {0}.{1}.”, 
  10:         args.Method.DeclaringType.Name, args.Method.Name), this.category); 
  11: }

3. Apply the aspect to one or more methods:

   1: [Trace(“MyCategory”)]
   2: private static void SayHello()
   3: {
   4:     Console.WriteLine(“Hello, world.”);
   5: }
   7: [Trace(“MyCategory”)]
   8: private static void SayGoodBye()
   9: {
  10:     Console.WriteLine(“Good bye, world.”);
  11: }

Altenratively you can apply the aspect to a whole namespace by specifying:

   1: [assembly: Trace(“MyCategory”, AttributeTargetTypes = “My.BusinessLayer.*”)]

4. Compile your application. When you install PostSharp it add itself to the default build process of MSBuild and it intervenes with the compiler work in order to add the relevant aspect’s code in the relevant targets. This is how the magic works!

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>