I’ve just released the first version of an Aspect Oriented framework for StructureMap onto nuget. This post will outline the basics of its use, while over the next few weeks I will delve into the more in-depth usages.

Wait, what’s Aspect Oriented Programming?

According to Wikipedia:

"In computing, aspect-oriented programming (AOP) is a programming paradigm which aims to increase modularity by allowing the separation of cross-cutting concerns."

The key is in the cross-cutting concerns bit: if you think about it, there will be a few features of your applications that are getting replicated and called all over the place. Most of the time these will include (but not be limited to):

  • Logging
  • Error handling
  • Diagnostics
  • Code security

Logging and error handling code is probably littered all over your application. Diagnostics and code security on the other hand you probably aren’t bothering with at all. AoP allows you to specify rules for this kind of stuff once and then get on with creating important code, safe in the knowledge that your rules are being enforced.

There are already AoP Frameworks out there, why use AspectMap?

  • It's pretty lightweight;
  • Setup us extremely simple and uses a fluent syntax familiar to anyone using StructureMap;
  • It can be injected into your application very quickly;
  • I'm actively developing it, your feedback will help shape future releases;
  • This post won't show you how to use the others;
  • It will make me smile!

This framework is built on top of the StructureMap IoC framework though, so if you can’t or won’t use StructureMap then you’re out of luck.

If you are familiar with IoC concepts and have used other containers (ninject, castle windsor etc) you should be able to follow along fine, if not I’d recommend working through the tutorials on the StructureMap site first. You’ll never look back!

Let's Go!

Start out by creating a new console application, and adding in the AspectMap nuget package from the online repository:

Add an interface an ITestClass. This will be the class doing our standard business logic:

public interface ITestClass
{
  void DoSomething();
}

And it’s implementation:

public class MyTestClass : ITestClass
{
  public void DoSomething()
  {
    Console.WriteLine("I'm doing something!");
  }
}

Now we’ll need a registry to wire up the objects. Note that this inherits from AspectMap.AspectsRegistry – we’ll need this for the aspects bit later:

public class MyRegistry : AspectsRegistry
{
  public MyRegistry()
  {
    For<ITestClass>().Use<MyTestClass>();
  }
}

For the last step in this simple setup add this code to your program’s Main method:

StructureMap.ObjectFactory.Initialize(x => x.AddRegistry(new MyRegistry()));
ITestClass testClass = ObjectFactory.GetInstance<ITestClass>();
testClass.DoSomething();
Console.ReadLine();

Run the program if you have any doubts about what will happen. Our goal is now to add some logging and exception handling on our code without adding any logic to the DoSomething() method itself.

Handler Nesting

Handler nesting is a term I just made up. It does describe the technique we’ll be using here quite nicely though. Add this code and then we’ll run through it:

using Castle.DynamicProxy;
public class LoggingHandler : AspectMap.AttributeHandler
{
  public override Action<IInvocation> Surround(Action<IInvocation> invocation, Attribute sourceAttribute)
  {
    return i =>
    {
      Console.WriteLine(i.Method.Name + " entered.");
      invocation(i);
      Console.WriteLine(i.Method.Name + " exiting.");
    };
  }
}

This handler is going to intercept the call to DoSomething (don’t worry about how yet) and wrap it in custom code – in this case writing out some logging info to the console, while calling the original invocation (DoSomething) in the middle. Note that we pass back an Action delegate instead of running the code at the time. This allows the result of this to be passed to another IAttributeHandler, in effect nesting one within another. Don’t worry if that went over your head, it will all make sense by the end!

Joining it up

If you run your code at the moment it will do absolutely nothing differently. What we need is a way of telling the LoggingHandler to intercept calls to DoSomething. Create a new attribute LoggingAttribute:

public class LoggingAttribute : Attribute {}

Now go and mark the DoSomething method (in MyTestClass not the interface) with LoggingAttribute:

[Logging]
public void DoSomething()
{
  Console.WriteLine("I'm doing something!");
}

Lastly, change the code in MyRegistry to this:

public MyRegistry()
{
  ForAspect<LoggingAttribute>().HandleWith<LoggingHandler>();
            
  For<ITestClass>().Use<MyTestClass>().EnrichWith(AddAspectsTo<ITestClass>);
}

The first line of this is telling the registry that methods marked with LoggingAttribute should be handled by the LoggingHandler class. This isn’t quite enough on its own though – we need to add the EnrichWith call onto the For<ITestClass> declaration.

Go ahead and run the application again, and lo and behold:

Pretty cool huh? You can now add this logging logic to any method you want with a maximum of two lines of code (one for the attribute, and one for the EnrichWith declaration). You also have a great level of control over the code application-wide though:

  • Want to turn off logging for DoSomething()? Remove the [Logging] attribute;
  • Want to turn off logging for all methods in MyTestClass? Remove the EnrichWith declaration;
  • Want to turn off logging application-wide? Remove the ForAspect<> line.

I hope this project helps to get you thinking in a new way, and that it will save you time on your own projects. In part 2 we’ll create an error-logging handler, a code security handler and discuss the concept of handler nesting in more detail.

This is a new project and so I’d love to hear any feedback, bug reports or feature requests. I’ll be open-sourcing AspectMap onto github once we hit version 1 as well. Get in touch!