Sunday, May 20, 2007

Finally, a Microsoft-sponsored AOP framework

It came out of the blue. Until the Patterns and Practices group in Microsoft release ThePolicy Injection application block as part of Enterprise Library 3.0, I would have never thought that Microsoft would ever release an AOP framework (or half an AOP frameword anyway). Especially since C# 3.0 and VB.NET 9.0 will introduce extension methods which go at least some of the way to let us inject Cross-cutting Concerns into classes that we don’t own or don’t want to clutter with code.

While mixins give os a way of letting foreign objects implement an interface in an ugly way, extension methods allow us to add new methods to existing classes in a nice looking way. The downside is that extension methods are more limited than mixins. Mixins can contain state, extension methods are just … methods.

AOP frameworks are there to provide two services to the developer: Mixins and interception. So far I’ve talked about mixins, but the Policy Injection application block (PIAB) doesn’t in fact provide mixins capability, only interception. And compared to other AOP frameworks it’s not that feature-rich at all. I still like it and here’s why.

What’s nice about PIAB is the way it’s integrated with the rest of Enterprise Library 3. It comes with ready made handlers that talk to the other blocks: Logging, Exception handling, Authorization, Performance counter, Caching and Validation. These cross cutting concerns cover 90% of what an average enterprise solution needs. And I can add new handlers and insert them into the handler pipeline. Handler code tends to be scattered in funny-named classes. This way it’s easy to organize sensibly.

I can get all that stuff if I’m ready to pay the price. And the price will always be the same (until the CLR starts supporting AOP or we get compile-time AOP like they have in the java world):

AOP is forcing us to 1) let our classes inherit from a certain baseclass, in this case MarshalByRefObject or to make all interceptable members virtual and 2) to never instantiate our objects using the new keyword. Instead an abstract factory is provided as part of the AOP framework. An PIAB is no exception to this rule. If you’re planning to plug PIAB into an existing project to get usage logging for example, you’d be forced to replace every instance of

Customer customer = new Customer();

with

Customer customer = PolicyInjection.Create();

The short term price is doing the search and replace. In the long run, your code gradually becomes more difficult to understand. If someone else from your team doesn’t know the convention to create objects this way, he’ll use “new” and suddenly everybody will be wondering why only some of the customers get intercepted by PIAB.

Mixins are a way to simulate multiple inheritance on an single inheritance runtime. But when PIAB requires us to inherit our business classes from a certain base class, we get no-inheritance instead of single inheritance. That can very well be a price you will be willing to pay, but you need to be aware of this before you decide to use PIAB.

If you’re not willing to pay this price and sell-out on the POCO principles there’s a nice in-between way: You get to choose the base class for your business classes, but then you will only get interception on the members that your class implements from a certain interface, that you specify. Often you’re not in a position to change the base class for foreign classes that you use, so this is a good alternative for those cases. You’ll still have to instantiate using the abstract factory though.

I’m not saying this to critisize PIAB or other AOP frameworks. They are made this way because it’s the only way. They all impose demands that go against POCO. The point is, you’ll want to know the limitations before starting using AOP in general and PIAB in particular. They are almost always mentioned as a footnote on page 64: “Oh by the way, to make any of this work, you’ll have to make all properties virtual and always instantiate objects using our factory.” What if the classes are provided without source code, then I can’t make their members virtual?

Maybe it’s time to reconsider POCO and become less religious about keeping classes clean. I’m looking forward to start using PIAB in the next real world project and to get some hands on experience. Anyway it’s great to know that AOP is moving from the dark-basement-experimental sphere to the enterprise-ready sphere.

For an in-depth discussion of the implementation choices in PIAB, see Ed Jezierski’s post.