Intro to Aspect Oriented Programming with PostSharp–Part 2

To Continue on from Part 1 lets dive a little deeper into Aspect Oriented Programming utilizing a framework called PostSharp

Setup

So the first way we will be introducing aspects into an application will be utilizing OnMethodBoundaryAspect.

This allows us to intercept a method call at 4 points.

  1. OnEntry – Before the body of the method is executed (called all the time)
  2. OnExit – After the body of the method is executed (called all the time)
  3. OnSuccess – Only happens if the code in the body executes without error.
  4. OnException – Only happens if the code in the body throws an exception.

So for our first example we are going to make a profiling aspect that only returns a message if a method takes longer than 2 seconds to execute. (you can follow along by looking at ProfileAttribute.cs in PostSharp-Aspects .

First thing we do is create a new class called ProfileAttribute (change to any name you want really).  General rule that I had explained to me is anytime you create an aspect end it with Attribute to make it easier to review without digging into the code.  Also make the class serializable.

After we create the class, inherit from OnMethodBoundaryAspect. Your class should look like this.

[Serializable] public class ProfileAttribute : OnMethodBoundaryAspect { }

For profiling we are going to utilize the OnEntry and OnExit entry points. (we will use OnSuccess and OnException at a later time).

Create an override to OnEntry that has a parm passed to it of type MethodExecutionArgs. In this method we want to add a Stopwatch.StartNew() to the args.MethodExecutionTab.

Then create an override to OnExit that also gets an parm passed to it of type MethodExecutionArgs.  In this method we will stop the stopwatch and then check the time to see if it took longer then 2 seconds to execute.  If it did write it out, if not just ignore it.

So our ProfileAttribute class should now look like this:

[Serializable] public class ProfileAttribute : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args);

        { 

          args.MethodExecutionTag = Stopwatch.StartNew();        }

         public override void OnExit(MethodExecutionArgs args)         {           var sw = (Stopwatch)args.MethodExecutionTag;           sw.Stop();            // only display if the method took longer than 2 seconds to execute           if (sw.Elapsed.TotalMilliseconds <= 2000)           {             return;           }           var messageOut = string.Format("{0} Executed in {1} seconds", args.Method.Name, sw.ElapsedMilliseconds / 1000);           Console.WriteLine(messageOut);        } }

Lets create a simple test method in our main application. Add a using statement if needed to the location of our aspects.  If you are using PostSharp-Aspects the statement will look like this.

using (applicationName).Aspects;

Then decorate our new method with the profile attribute.  It should look similar to like this:

[Profile]

public static void Blablabla2(){ Thread.Sleep(3000) Console.WriteLine("this is a test");}

When we build our application the compiled code will look similar to this:

public static void Blablabla2()
{ MethodExecutionArgs methodExecutionArg = new MethodExecutionArgs(null, null); MethodBase methodBase = Program.m2; methodExecutionArg.Method = methodBase; Program.a0.OnEntry(methodExecutionArg); try { Thread.Sleep(3000); Console.WriteLine("this is a test"); } finally { Program.a0.OnExit(methodExecutionArg); }
}

If we run our application we will see the following output:

CropperCapture[7]

I will post the code examples as soon as I figure out where I want to host them. In a toss up between codeplex, bitbucket, or github.  Any opinions are greatly appreciated.

Shoutout: PostSharp team has created a collection of ready-made aspects in the PostSharp ToolKit.  Please visit and read about it, some great stuff.

This entry was posted in PostSharp and tagged , , . Bookmark the permalink.