I 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.

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:

Cool stuff!
Hope you enjoy the screencast. Check out other Patterns & Practices Screencasts.
David Hayden