Aspect Oriented Programming in .Net using PostSharp

I saw this arti­cle on D. Patrick Caldwell’s blog a lit­tle while back:

http://dpatrickcaldwell.blogspot.com/2009/03/validate-parameters-using-attributes.html

It was this arti­cle that got me inter­est­ed in Post­Sharp and the pos­si­bil­i­ties that it can bring. Post­Sharp, in short, is a light­weight frame­work which intro­duces some Aspect-Ori­ent­ed Pro­gram­ming into .Net.

Some of the com­mon usages I have seen include trac­ing and the ‘mem­o­riz­er’ (again, from D. Patrick Caldwell’s blog) being one of the more inter­est­ing. There is also a blog entry over at Richard’s Brain­dump which high­lights how you can use Post­Sharp to imple­ment the INo­ti­fyProp­er­ty­Changed inter­face.

One thing I’d like to point out though, is that the para­me­ter val­i­da­tion tech­nique in D. Patrick Caldwell’s blog entry above should be used with care and you should avoid apply­ing the [Check­Pa­ra­me­ters] attribute at class/assembly lev­el as it does car­ry some per­for­mance hits. After play­ing around and exper­i­ment­ing with it for a lit­tle while, I have set­tled on apply­ing the [Check­Pa­ra­me­ters] attribute only on meth­ods whose para­me­ters require val­i­da­tion.

In my line of work, we have a lot of prob­lems with dead­locks in the Data­Base due to the num­ber of dif­fer­ent appli­ca­tions using the same Tables in the Data­Base and the dif­fer­ent way they use these tables (some uses nolock, oth­ers don’t). As a result, there are a lot of boil­er­plate code in the DAL class­es which catch­es SqlEx­cep­tions and in case of dead­locks or con­nec­tion time­outs retry up to x num­ber times. This, of course, is a cross-cut­ting con­cern, and by employ­ing Post­Sharp I am able to deal with them with a sim­ple attribute like the one below instead of hun­dreds and hun­dreds lines of code.

[Serializable]
[AttributeUsage(AttributeTargets.Method)]
public class RetryOnSqlDeadLockOrConnectionTimeOutExceptionAttribute : OnMethodInvocationAspect
{
     [NonSerialized]
     private int CurrentAttempt;

     public override void OnInvocation(MethodInvocationEventArgs eventArgs)
     {
          CurrentAttempt++;

          try
          {
               eventArgs.Proceed();
          }
          catch (SqlException sqlException)
          {
               if (sqlException.Number == -2 || sqlException.Number == 1205)
               {
                    // put retry logic here
               }
               else
                    throw;
          }
     }
}

and to use it:

[RetryOnSqlDeadLockOrConnectionTimeOutException]
public void SomeDataBaseBoundOperationWhichNeedsRetryOnDataBaseDeadLock()
{
     ...
}