Freekshow

October 2, 2008

PostSharp: AOP for .Net

Filed under: .Net,AOP,Open Source — Freek Leemhuis @ 10:10 am

The updates to Microsoft’s reference architecture (find them on www.codeplex.com/AppArch) got me thinking about what a good reference implementation would be when adopting Domain Driven Design.

For now let’s focus on cross-cutting concerns, as they are depicted in the reference architecture.

 

The cannonical example for a cross-cutting concern is logging, and I’ve come across quite a few applications that had logging code scattered across the entire application. A better way to separate these concerns is by using Aspect Oriented Programming (AOP). In the .Net world there’s only a few frameworks that deal with AOP, and of these PostSharp is probably best known. The Enterprise Library ofcourse has the Policy Injection Application Block, which has similar functionality.

I have been spending some time with PostSharp, and I really like the improvement it can bring in the application design. And it’s really not hard to do. I’ll give a quick example: 

After you’ve installed the PostSharp bits you’ll need to include two references, to PostSharp.Laos and PostSharp.Public.

First, you wil need to create an aspect class, let’s name it TraceAspect.

[Serializable]
public sealed class TraceAspect : OnMethodBoundaryAspect       
{
    public override void OnEntry(MethodExecutionEventArgs eventArgs)
    {
       Console.WriteLine("User {0} entering method {1} at {2}" , Environment.UserName, eventArgs.Method , DateTime.Now.ToShortTimeString());           
    }
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
       Console.WriteLine("User {0} exiting method {1} at {2}", Environment.UserName, eventArgs.Method, DateTime.Now.ToShortTimeString());
    }
}

A few things to note here:

  • You will need to mark the class with the Serializable attribute.
  • The OnMethodBoundaryAspect actually extends the Attibute class, so it’s like you’re creating a custom Attribute.
  • We’re implementing the aspect handlers by overriding the designated base class handlers, in this case OnEntry and OnExit.

Were now ready to apply the postsharp attribute to our classes to add tracing

class Program
    {
        static void Main(string[] args)
        {
            Customer cust = GetCustomer(1);
            SaveCustomer(cust);
            Console.ReadKey();
        }

        [TraceAspect]
        public static Customer  GetCustomer(int customerId)
        {
            Console.WriteLine("GetCustomer is executing");
            System.Threading.Thread.Sleep(2000); //taking it's time...
            return new Customer { FirstName = "Private", LastName = "Ryan" };
        }
        [TraceAspect]
        public static void SaveCustomer(Customer customer)
        {
            Console.WriteLine("SaveCustomer is executing");
            System.Threading.Thread.Sleep(3000); //taking it's time... again...
        }

        public class Customer
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }
    }

As you can see ,there’s not much to it but adding the [TraceAspect] attribute to our class. When executing this little sample you’ll get the expected output:

The magic is performed for us here by invoking the post-compiler that it uses to weave the AO code into the IL

So that when you use Reflector (I almost added Lutz’s name here…) to look at your final assembly, you can see the weaving that has been done:

PostSharp is a very powerful tool and it’s capable of a lot more than what I can show here. It’s a bit of a one-man band behind it, but it’s creator Gael Fraiteur has done a fine job of releasing it to open source and it’s actually got good documentation. Check it out on www.postsharp.org

 

Advertisements

Blog at WordPress.com.