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.
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.
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.