PostSharp AOP and Unity IoC Container - Alternative to Interception Extension and RemotingPolicyInjector

Patterns & PracticesI created a screencast the other day called:

which showed off the new Unity Interception Extension and RemotingPolicyInjection in Unity v1.2 ( still in development ).

This got me thinking about a presentation I did for IASA Tampa on AOP, where I showed off the Policy Injection Application Block, PostSharp, Castle Windsor, and various other tools:

Similar to the IASA Tampa Bay Presentation where I compared and contrasted the various alternative tools using the same scenario, I thought I would provide some code using PostSharp 1.0 that does the same thing as mentioned in the screencast. For background please watch the screencast where I walk through the details of the sample using Unity. All I plan to do here is show some code using PostSharp Laos with very brief commentary. My only point is that there are many, many ways to solve a problem. It is nice to understand the alternatives as well as their pros and cons. You can learn more about PostSharp at PostSharp.org.

In the screencast I created a custom HandlerAttribute and ICallHandler that invokes the Stopwatch Attribute Class and prints out the time it takes for the ILogger.Write Method to execute. Again, see the screencast for details. I can do the same thing with PostSharp Laos, but instead create a StopwatchAttribute that derives from OnMethodBoundaryAspect:

 

[Serializable]

public class StopwatchAttribute : OnMethodBoundaryAspect

{

    public override void OnEntry(MethodExecutionEventArgs eventArgs)

    {

        var sw = new Stopwatch();

        sw.Start();

        eventArgs.MethodExecutionTag = sw;

    }

 

    public override void OnExit(MethodExecutionEventArgs eventArgs)

    {

        var sw = (Stopwatch)eventArgs.MethodExecutionTag;

        sw.Stop();

 

        Console.WriteLine();

        Console.WriteLine(string.Format("Time Elapsed: {0} ms", sw.ElapsedMilliseconds));

    }

}

 

I can then decorate my Logger's Write Method with the Stopwatch Attribute as such:

 

public interface ILogger

{

    void Write(string message);

}

 

public class Logger : ILogger

{

    [Stopwatch]

    public void Write(string message)

    {

        Console.WriteLine();

        Console.WriteLine("*** In Logger ***");

        Console.WriteLine(string.Format

            ("message : {0}", message));

    }

}

 

When I register the logger with Unity and run the application:

 

static void Main(string[] args)

{

    IUnityContainer container = new UnityContainer();

    container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());

 

    ILogger logger = container.Resolve<ILogger>();

    logger.Write("Hello!");

 

    Console.ReadLine();

}

 

it displays the results of the Stopwatch's Elaspsed Time in a console window. Notice that I don't need to use the Interception Extension or the RemotingPolicyInjector in this case. PostSharp Laos will be handling the interception via IL Weaving during the post-compile.

 

PostSharp Unity

 

 

The interesting part is what PostSharp Laos does under the covers. It does a bit of IL Weaving and changes the Logger.Write Method into a Try/Catch/Finally Block that calls your Stopwatch Attribute Code inline to the method. No better way to see this than with Reflector:

 

PostSharp Unity Reflector

 

 

Cool stuff!

Hope you enjoy the screencast. Check out other Patterns & Practices Screencasts.

David Hayden

 

posted on Saturday, September 27, 2008 9:50 PM

Main

News

Green Tea

.NET Development

Enterprise Library

Patterns & Practices