C#/AOP: Elegant tracing with PostSharp and Aspect-Oriented Programming
My post yesterday was about Python decorators and in that post I used the example of tracing to illustrate how to use Michele Simionato’s decorator module.
As a fan of comparative code samples, with this post I’ll show you how to accomplish the same thing with C#.
Unlike the Python sample, it' doesn’t involve using another library. Instead this solution requires the use of an Gael Fraiteur’s Aspect-Oriented tool called PostSharp.
The Starting Point
Let’s look at the base source code. It’s just a method called foo() that prints “Hello World”
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DemoPostSharpTracing
{
class Program
{
static void foo()
{
System.Console.WriteLine("Hello World");
}
static void Main(string[] args)
{
foo();
}
}
}
This is the output.

Now let’s add some tracing
First install PostSharp 1.0


Add References to these two assemblies
- PostSharp.Laos
- PostSharp.Public
Now create an attribute that prints an entry and exit message.
[Serializable]
public class TraceAttribute : PostSharp.Laos.OnMethodBoundaryAspect
{
public override void OnEntry(PostSharp.Laos.MethodExecutionEventArgs eventArgs)
{
Console.WriteLine("ENTER {0}.", eventArgs.Method);
}
public override void OnExit(PostSharp.Laos.MethodExecutionEventArgs eventArgs)
{
Console.WriteLine("EXIT {0}.", eventArgs.Method);
}
}
The name of the attribute class is “TraceAttribute” so just add “Trace” as an attribute to foo()
[Trace]
static void foo()
{
System.Console.WriteLine("Hello World");
}
So the full source code will look like this. Red marks the changes from the code we started with.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DemoPostSharpTracing
{
[Serializable]
public class TraceAttribute : PostSharp.Laos.OnMethodBoundaryAspect
{
public override void OnEntry(PostSharp.Laos.MethodExecutionEventArgs eventArgs)
{
Console.WriteLine("ENTER {0}.", eventArgs.Method);
}
public override void OnExit(PostSharp.Laos.MethodExecutionEventArgs eventArgs)
{
Console.WriteLine("EXIT {0}.", eventArgs.Method);
}
}
class Program
{
[Trace]
static void foo()
{
System.Console.WriteLine("Hello World");
}
static void Main(string[] args)
{
foo();
}
}
}
And this is the output
Nice!
Now we can simply turn on tracing for a function just by annotating it with the [Trace] attribute.
Parting Thoughts
- Please keep in mind I picked the simplest possible example. You can do more with PostSharp and AOP that tracing.
- Notice the [Serializable] attribute on the TraceAttribute class. This was necessary for me to get project to compile. However, it’s not entirely clear to my why the the class needed to this attribute.
- One of the great features of PostSharp is that it integrated with the MSBUILD process so that there were no extra configuration steps – it works “out-of-the-box”.