# Sunday, November 25, 2007

Background Information

Aspect Oriented Programming has been on my list of things to read up on for almost a year now.  It likely would have stayed on my list of things to do well into the future if it hadn't been for a recent .NET Rocks episode.  I can't recall if it was the Pablo Castro on Astoria, or the Tim Sneath and Ian Ellison show, but one of them off-hand mentioned PostSharp.  As I usually do when links are thrown about on the show, I scribbled it on my hand for later review. Update DNR just released a show with Gael Fraiteur of PostSharp fame!

Once I got to the PostSharp site, I found their sample video on creating a trace AOP attribute.  They had me hooked.  I wasn't so much interested in doing a logging or trace attribute, but was more interested in doing a few validation attributes.  More specifically a NotNullAttribute.

The Problem

What got me interested in doing the NotNullAttribute was thinking back to how many times in our code base we would have something like this:

1 public void AddUser(Organization org, User user) 2 { 3 if (org == null) 4 throw new ArgumentNullException("org"); 5 if (user == null) 6 throw new ArgumentNullException("user"); 7 8 org.AddUser(user); 9 _ordDal.Save(org); 10 }

Granted this is a somewhat short method, but we have methods which take 6 parameters, and only 2 actual lines of code.  That's 12 lines of code taken up for argument checking, and 2 lines of code.  That would put our crap to code ratio at 6/1.

The Solution

Wouldn't it be much nicer if you could do something like this:

1 public void AddUser([NotNull] Organization org, [NotNull] User user) 2 { 3 org.AddUser(user); 4 _ordDal.Save(org); 5 }


PostSharp is almost there to let you write code just like that.  Currently, there is no support for an OnParameterAspectBoundaryAttribute in PostSharp, so we have to do things just slightly differently:

[NotNullHelper] public void AddUser([NotNull] Organization org, [NotNull] User user) { org.AddUser(user); _ordDal.Save(org); }

We have to have a helper class were all the actual code lives.

How PostSharp Works

PostSharp works by weaving all your AOP attributes with your source code after the compiler compiles your code.  This article by Gael Fraiteur describes in more detail how the PostSharp process works.  After the code is post-compiled by PostSharp, you end up with something very ugly that looks like this:

public void AddUser([NotNull] Organization org, [NotNull] User user) { MethodExecutionEventArgs ~laosEventArgs~2; try { object[] ~arguments~1 = new object[] { org, user }; ~laosEventArgs~2 = new MethodExecutionEventArgs(methodof(OrgManager.AddUser, OrgManager), this, ~arguments~1); ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnEntry(~laosEventArgs~2); if (~laosEventArgs~2.FlowBehavior != FlowBehavior.Return) { org.AddUser(user); _orgDal.Save(org); ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnSuccess(~laosEventArgs~2); } } catch (Exception ~exception~0) { ~laosEventArgs~2.Exception = ~exception~0; ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnException(~laosEventArgs~2); switch (~laosEventArgs~2.FlowBehavior) { case FlowBehavior.Continue: case FlowBehavior.Return: return; } throw; } finally { ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnExit(~laosEventArgs~2); } }

I don't know about you, but I would have one HELL of a time trying to debug this, thankfully PostSharp touches up the PDB files, so when your debugging, you only see and debug the source code you've written, both your attribute, and your business logic.

The Drawbacks

PostSharp modifies your code! Well, not directly, but it is still modifying your code (as seen above), but thankfully it touches up the PDB files so all the mess under the hood is hidden from you.


This is but one of the many things you can do with AOP and PostSharp.  Next up, I plan to write some validation attributes.  Look for those in the next few weeks.  In the mean time, download the source code for the NotNullAttribute.

I'm sorry if this post looks terrible in your feed reader, I still haven't been able to figure out why the code looks terrible.  If anyone has any suggestions, let me know.  I'm using DasBlogCE as my blog engine.

kick it on DotNetKicks.com
.NET | AOP | C# | PostSharp
Sunday, November 25, 2007 8:37:23 PM (Alaskan Standard Time, UTC-09:00)