Tuesday, 19 February 2008

This is the second of a series about how to go about using postcompilation in your solutions. You can read it as a tutorial on how to use PostSharp. I am very much a new to that framework, but the power it provides could seriously change how you build your applications. While working on the EF contrib project, I had to dive into PostSharp, and I hope to share some of the things I learned along the way.

This post quickly introduces PostSharp, before we move on to the real stuff!

The full table of contents:

PostSharp

The PostSharp home introduces PostSharp as follows:

PostSharp is a tool that can reduce the number of lines of code and improve its logical decoupling. Therefore its helps you delivering higher stability, cleaner design, and cheaper source code maintenance

And best of all, PostSharp is free and open source. Yes, even for commercial use

Basically, it allows you to use attributes on top of code to indicate that after the normal visual studio compilation, PostSharp should do 'something' to the code. That 'something' could be anything you want. The result is a compiled assembly that does more than you would expect from the sourcecode. This is a good thing, when you have 'code noise': code that might be important, but distracts from the real work.

Code noise could be your logging mechanism, or your transaction mechanism. In my case, I did not want to implement the IPoco interfaces that EntityFramework needs, in order to make my business objects work with EntityFramework. I want my business objects to represent a person, car or whatever, and not have to deal with the data access logic at all.

The simplest example you can think of, is shown on the frontpage:

public class SimplestTraceAttribute : OnMethodBoundaryAspect 

  public override void OnEntry( MethodExecutionEventArgs eventArgs) 
  { 
    Trace.TraceInformation("Entering {0}.", eventArgs.Method); 
    Trace.Indent(); 
  } 
  public override void OnExit( MethodExecutionEventArgs eventArgs) 
  { 
    Trace.Unindent(); 
    Trace.TraceInformation("Leaving {0}.", eventArgs.Method); 
  } 
}

By adding an [SimplestTrace] attribute on top of your code, you will have instant tracing information, without actually seeing it in your code. The fun thing about PostSharp is, that this code is actually in your assembly after post-compilation, as opposed to other AOP frameworks, that will do it at runtime.

Laos versus Core
PostSharp offers a full representation of your code, a bit like reflection. But it can be hard to work with. That is why PostSharp Laos was created. Laos is a 'plugin' on the core functionality that abstracts away most of the hard stuff, and leaves you with ready to implement aspects.

I found it wildly confusing the first time I came across the two parts of postsharp. Laos is such a high-level abstraction, that you use it quite differently from Core. In the latter, you have to spinup your own weaver, in Laos you do not ever see a weaver.
(A weaver is a class that will actually inject IL methods into your assembly.)

When you use Laos, some smart hooks exist to use it's own weaver. That weaver knows how to deal with Laos Aspects. And so, you can use the Laos abstractions without any knowledge about IL or weaving.

The shown example uses the OnMethodBoundaryAspect, from Laos. The Laos weaver will inject the necessary IL methods on every method (that matches your desire to trace it) to call the OnEntry and the OnExit methods you defined. There are quite a few aspects ready to inherit from. I urge you to look at the documentation to find out which.

If you were to implement that functionality using the Core library, you would have to inject all the IL yourself. It would however, give you the opportunity to actually inject the Trace calls into the methods, instead of the easier method calls.

One very interesting aspect that Laos offers, is the CompositionAspect, which allows you to set a specific interface to implement and give an implementation object that is called for every defined method on the interface. I use it for the three IPoco interfaces.

In short: Laos is a very high-level abstraction that will get you very far. In some cases you need to take it a little further, and you will need Core.

 

In the next couple of posts, I will show both the Laos aspects and the Core aspect, how they were applied and how they do their job.

Friday, 15 October 2010 12:29:39 (Romance Standard Time, UTC+01:00)
That is the type we have adorned with our attribute (your 'Person' Poco class, for instance). Then, I specify that I want 3 other aspects to work on this type!
Comments are closed.