Aspect Orientated Programming (AOP) - A Brief look at PostSharp

April 15, 2016 by C#   Threading   PostSharp  

Before I jump into the subject at hand, I just want to make a little confession.

The very first time I looked at the whole AOP paradigm (many moons ago), I was a victim of authority bias, I solely accepted the opinions of one of our industry leaders, without any investigation and making up my mind for myself.

More doctors smoke Camels

The thing we need to remember however, is that just like with everything else, AOP can be abused in the wrong hands, which hardly disqualifies it of anything.

I honestly still have my reservations, but I am warming up to it a bit.

But what is AOP all about exactly?

It is all about the separation of the common functionality that span over layers and tiers (e.g. logging, caching, security, validation, benchmarking etc), known as cross cutting concerns, which the various AOP frameworks attempt to achieve with little or no modification to existing source code.

To demonstrate, my poison of choice is C# and a popular AOP solution called PostSharp.

Lets assume for a second that I want to benchmark the performance of some of my code, one way to achieve this would be to instantiate a Stopwatch, like seen below.

using System;
using System.Threading;
using System.Diagnostics;
using static System.Console; class Program { static void Main(string[] args) { var stopWatch = new Stopwatch(); stopWatch.Start(); Thread.Sleep(5000); stopWatch.Stop(); WriteLine($"void Main at {stopWatch.Elapsed}"); } }

The biggest problem I have with this approach is that we've introduced code into the codebase that isn't of real intrinsic value to the ultimate goal of the application. Sure it is very handy for pinpointing potential bottlenecks, but its unnecessarily contaminating our codebase.

Now have a look at the same snippet rewritten to make use of a custom aspect.

class Program
{
    [Profiler]
    static void Main(string[] args)
    {
        Thread.Sleep(5000);
    }
}

This is quite neat, the method body now only contains the relevant code to whatever problem we're trying to solve.

And creating the custom aspect was quite simple as well, have a look at its implementation below.

using System;
using System.Threading;
using System.Diagnostics;
using PostSharp.Aspects;
using static System.Console;

[Serializable]
class ProfilerAttribute : OnMethodBoundaryAspect
{
    [NonSerialized]
    Stopwatch stopWatch;

    public override void OnEntry(MethodExecutionArgs args)
    {
        stopWatch = new Stopwatch();
        stopWatch.Start();
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        stopWatch.Stop();
        Debug.WriteLine($"{args.Method} at {stopWatch.Elapsed}");
    }
}


In addition to the two overrides in the snippet above, we're also able to override the OnException method (among others), if you would like to handle those exceptions however, you will need to inherit from the OnExceptionAspect class (remember what I said about abuse).

The PostSharp solution also provides us with common patterns (stuff like contracts - precondition checking, logging and threading).

I am not going to go into too much detail in this post, I would however like to elaborate on the threading aspects a little bit.

The threading aspect library aims at creating thread safe code by providing, threading models (freezable, immutable etc), thread dispatching (background, dispatch) and deadlock detection.

To give you a quick overview of the dispatching aspects, observe the following snippet.

using PostSharp.Patterns.Threading;
using System;
using System.Threading;
using System.Windows.Forms;

class TestForm : Form
{
    TextBox textBox = new TextBox();

    public TestForm()
    {
        this.Controls.Add(textBox);
        this.Load += new EventHandler(TestForm_Load);
    }

    [Background]
    void TestForm_Load(object sender, EventArgs e)
    {
        Thread.Sleep(5000);
        setTextBox();
    }

    [Dispatched]
    public void setTextBox()
    {
        textBox.Text = "dude";
    }
}

class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new TestForm());
    }
}

Very clean, instead of instantiating a BackgroundWorker and attaching events to it, we simply decorate our worker method with a Background attribute, while decorating the method that writes back to the UI thread with a Dispatched attribute.

I would love to see how these two aspects operate using a more complex scenario though (I didn't see a thread cancel attribute for example), would this be any better than writing more traditional code?

One last thing to note before I go outside and sidestep all the dangerous wildlife, is that this library isn't free (the good parts at least), it is quite pricey (especially if you're living in the third world like me).

It will be interesting to see how open source libraries compare.

Additional Reading

PostSharp Documentation
AOP in C#? Over Anders Hejlsberg's Dead Body!
Chapter 17: Crosscutting Concerns
Chapter 2: Key Principles of Software Architecture


Leave a Comment