Ayende @ Rahien

It's a girl

First Steps with Post Sharp

PostSharp is an AOP framework that works using byte code weaving. That is, it re-writes your IL to add behaviors to it. From my point of view, it is like having the cake (interception, byte code weaving) and eating it (I haven't even looked at the PostSharp source code, just used the binary release).

My initial spike with it went very well. Here it is:

[Serializable]
public class Logger : OnFieldAccessAspect
{
    public override void OnGetValue(FieldAccessEventArgs eventArgs)
    {
        Console.WriteLine(eventArgs.InstanceTag);
        Console.WriteLine("get value");
        base.OnGetValue(eventArgs);
    }

    public override InstanceTagRequest GetInstanceTagRequest()
    {
        return new InstanceTagRequest("logger", new Guid("4f8a4963-82bf-4d32-8775-42cc3cd119bd"), false);
    }

    public override void OnSetValue(FieldAccessEventArgs eventArgs)
    {
        int i = (int?)eventArgs.InstanceTag ?? 0;
        eventArgs.InstanceTag = i + 1;
        Console.WriteLine("set value");
        base.OnSetValue(eventArgs);
    }
}

This is an aspect that run on each field access. It is not really useful, but it helps to show how things works. A couple of things that are I think are insanely useful:

  • Aspects are instantiated at compile time, allowed time to set themselves up, then serialized to an resource in the assembly. At runtime, they are de-serialized and ready to run. The possibilities this give you are amazing.
  • InstanceTag is a way to keep additional data per aspect.

Now, let us assume that I want to add the aspect to this code:

[Logger]
public class Customer
{
    public string Name { get; set; }
}

Note, there is no field. (Well, there is, it is generated by the compiler). Now we compile and run the PostSharp post compile step. With that, we can now investigate what is going on.

image

As you can see, we are deserializing the attribute and storing it in a field that we can now access. Let us check the Customer implementation now:

image

We have the logger field, which is used for something, but we also have the ~get~<Name>k__Backingfield and ~set~<Name>k__BackingField. <Name>k__BackingField (and I would love to hear the story behind that) is the compiler generated field that was created for us. The ~get~... and ~set~ are generated by PostSharp. Before we look at them, we will look at the implementation of Name.

image

Where it used to call the field directly, now it is doing this via a method call. And now we can look at those method calls.

image

There is a lot going on here. We create a new field access event arg, call the aspect method, and return the value. Note that the state (instance tag) is stored in the object as well, for each field access.

It looks very well done.

Comments

Chris Ortman
10/09/2008 08:37 PM by
Chris Ortman

What happens when you need to debug your code? Do the [Debugger] attributes let you step through your code as you wrote it ignoring the PostSharp goo?

Oğuz Kurumlu
10/09/2008 09:08 PM by
Oğuz Kurumlu

@Chris

You can debug your code and your aspects like you write. Debugging is verry well with postsharp.

liviu
10/09/2008 09:51 PM by
liviu

Postsharp is great, but i think something changed between versions.

I noticed that it generates the IL source code!!! I posted with consternation on the forum and it was confirmed by Frateur.

In my simple projects it is very slow. I have a machine above average, 4G DDR2, best Raptor150, it is unacceptable from my point of view.

I don't have this problem with boo macros :-), where although a newbie, the performance is simply great.

I would move my codebase to boo if it were 1.0....

Stephen
10/09/2008 09:53 PM by
Stephen

Really cool, I keep wondering if aspect orientated stuff will make it into c#'s next version.. not sure if that would be classed as polution of the language.

pete w
10/10/2008 12:44 AM by
pete w

I've pulled in postsharp for things like:

-singleton

-Inotifypropertychanged

-validation

its occasionally a worthwhile trick to cut back on repetitive code

I pitched in some examples on:

http://code.google.com/p/postsharp-user-samples/

this kind of thing comes for free in Boo, doesnt it?

Sean Kearon
10/10/2008 07:44 AM by
Sean Kearon

@liviu - I use PostSharp to give me property changed notification and to do some other set up in my object model. I have a lower spec machine than you and have no major problems with speed. Sure, it's noticable during the compile, but only a few extra seconds. As I see it now it's well worth the massive simplification to my domain objects. What are you using PostSharp for? I'm interested in case there are some gotchas waiting for me!!

Steve
11/18/2008 08:23 PM by
Steve

Does this work with virtual properties ?

I'm not getting it to work, was wondering if that is why

Comments have been closed on this topic.