Appendix A. Ecosystem of .NET AOP tools

The majority of this book focuses on two major general-purpose AOP tools for .NET: PostSharp and Castle DynamicProxy. I often paired Castle DynamicProxy with StructureMap, which is an IoC container. I also touched briefly on more specific-purpose tools, including NotifyPropertyWeaver, ASP.NET MVC ActionFilters, and ASP.NET HttpModules.

These are the tools I am most familiar and comfortable with, and that’s why I chose them as the canvas on which to write about AOP. However, there are many tools in the .NET space that also allow you to write and use aspects. My intention is that this book will teach you how to use PostSharp and Castle DynamicProxy in-depth and help you explore the breadth of other tools.

This appendix is a crash course on tools that fit into two categories:

  • Compile-time AOP tools. Like PostSharp, these tools make themselves part of the build process and modify the compiled CIL to perform weaving.
  • Runtime AOP tools. Like Castle DynamicProxy, these tools generate decorators at runtime using Reflection, and they are usually closely related to an IoC tool (such as Castle Windsor).

For each tool, I’ll give a very simple example of how to use it, much like the “Hello, World” aspect from chapter 1. My goal is to show you that even though the APIs change and features vary, the essentials of AOP are present in each tool. The intention of this appendix isn’t to be an exhaustive list of every tool. Inclusion in this appendix does not mean that I endorse the tool; exclusion does not mean that I reject the tool.

I haven’t used every tool to the same extent that I’ve used PostSharp and Castle DynamicProxy. Look at this appendix as the first step in a journey to find the tool or combination of tools that’s right for you.

A.1. Compile-time AOP tools

A compile-time AOP tool uses a postcompiler to analyze the CIL created by the C# compiler. These tools then make changes by directly manipulating the CIL. In this section, we’ll examine some of the tools that belong to this family.

A.1.1. PostSharp

PostSharp is the tool I’ve spent the most time on in this book, so there’s no need to say much more about it here.

The stable release when most of this book was written was PostSharp 2.1, but PostSharp 3 is now officially released. The focus of PostSharp 3 is to start putting more emphasis on design pattern automation, which basically means that PostSharp will emphasize prewritten aspects that are ready to be applied to your code. PostSharp Ultimate is a major part of that: it has a collection of aspects that are ready to use in your project. (They do require a commercial license of PostSharp to use.)

Although design pattern automation becomes the focus of the PostSharp product, the ability to write your own aspects is still a major part of the product, and I don’t believe the need to write your own custom aspects will ever go away.

A.1.2. LinFu

LinFu is a library that contains many features, including dependency injection, mixins, and AOP capabilities. LinFu is unique because it provides compile-time AOP capability as well as runtime AOP capability. So it’s a “hybrid” AOP tool.

LinFu can be added from NuGet (Install-Package LinFu.Core). In the following listing I’ve created a familiar aspect example that writes to Console before and after a method.

Listing A.1. Simple LinFu example

Like Castle DynamicProxy, LinFu is meant to work with an IoC container (such as the LinFu IoC container).

Additionally, you have to make changes to your project file so that an MSBuild task runs the LinFu postcompiler after normal compilation. This listing shows an example of how that might look.

Listing A.2. Modifying project file to add PostWeaveTask

Once that AfterBuild task is in place, running the program should give you a Console output such as this:

On the plus side, LinFu is free and open source and available on GitHub. However, LinFu’s documentation is somewhat limited. There is example code in blog posts and the GitHub repository. The LinFu project has a lot of potential, but at the time of this writing, according to GitHub, the LinFu source code hasn’t been updated in a year, and there are outstanding issues from almost a year ago that have not been addressed.

But because it is an open source project, it’s definitely worth checking out if you are interested in learning more about the details of postcompile weaving. LinFu appears to use both Mono.Cecil and Microsoft.Cci, both of which are briefly discussed later in this appendix.

A.1.3. SheepAspect

SheepAspect is inspired by AspectJ for Java. It is something of a newcomer to AOP in .NET. It’s an open source project that has appeared within the last year and has made positive strides in the area of features and documentation in a short time.

With SheepAspect, you define everything together in a single class, including pointcut and advice. A pointcut is defined by creating an empty method which will have one or more attributes that specify the pointcut. Another method is defined that contains the advice. This method is tied to the pointcut via another attribute.

Add SheepAspect to a new Console project with NuGet (Install-Package SheepAspect). The NuGet installation will automatically make changes to your project so that the postweaving task will run. For the next listing I’ve written what should be a familiar example at this point: a very basic aspect that writes to Console before and after a method.

Listing A.3. Simple SheepAspect example

The console output of that program is what you would probably expect:

In the SelectMethod attribute, the string argument consists of SAQL, the SheepAop Query Language. This is the most intriguing feature of SheepAspect, because it gives you a lot of options and control in defining pointcuts.

This tool is very promising, and if it keeps up the rate of development and documentation, it is definitely a tool to keep an eye on. It’s currently classified as an alpha release.

SheepAspect uses the Mono.Cecil library to perform CIL manipulation, which is one of several CIL manipulation tools available.

A.1.4. Fody

Fody is a compile-time tool that is more general purpose, but it warrants including in this appendix. Fody isn’t referred to as an AOP tool; instead it’s called an extensible tool for weaving .NET assemblies. That certainly includes the ability to write aspects or at least aspect-like functionality. Fody’s strength lies with its extensibility and its flexibility.

Like PostSharp Ultimate’s ready-made aspects, Fody takes a modular approach to introducing functionality. Along with the core Fody framework, you also install one (or more) add-ins, that provide functionality through CIL manipulation. There are 25 add-ins with functionality, much the same as what we’ve covered in this book, including PropertyChanged (for INotifyPropertyChanged), Virtuosity (changes all members to virtual, which could be helpful with NHibernate or other tools that rely on Castle DynamicProxy), and NullGuard (defensive programming).

For more general-purpose AOP, you can also use a plugin like MethodDecorator, which gives you a way to write method boundary aspects. Install with NuGet (Install-Package MethodDecorator.Fody). The NuGet install will modify your project and add a few files to it, and you’ll be ready to go.

Listing A.4. Simple MethodDecorator example

Additionally, there are other plugins that aren’t strictly AOP-related, but they are useful bits of functionality that can make coding easier. An add-in called Scalpel removes tests from an assembly, which could be useful when building deployment packages. Another add-in called Stamp automatically adds git information to an assembly’s AssemblyInformationVersion. This flexibility that Fody brings allows you to accomplish a variety of tasks outside of the normal realm of AOP.

Of course, Fody’s extensibility means that you can write your own add-ins. Writing these plugins can be more difficult than writing aspects, because you often have to use Mono.Cecil, work with CIL op codes, and make sure that the resulting assembly is valid (with a tool like PEVerify).

Fody is an open source project that is being actively maintained, and is principally authored by Simon Cropp (who also created the NotifyPropertyWeaver tool that was mentioned in chapter 5). Like NotifyPropertyWeaver, Fody tends to rely on convention over configuration, which works well when the conventions are clear. Although this tool is less than a year old, it is still quite impressive, well documented, and definitely worth exploring.

A.1.5. CIL manipulation tools

If you want to write your own CIL-manipulating AOP framework, then you might consider using one of the following existing CIL manipulation libraries. Use of these libraries requires a thorough knowledge of CIL; they are for very advanced development. Additionally, documentation is often scant, and there are few practical examples available.

Mono.Cecil

Cecil is part of the Mono project, which is an open source implementation of the .NET framework. Cecil allows you to examine and modify .NET assemblies. It is free, and has been used by a few open-source AOP frameworks (including SheepAspect).

PostSharp SDK

The main PostSharp library is called PostSharp.dll, which is what we used throughout this book. This is a library that contains base classes and other API elements that you need to build and use aspects.

Another library, PostSharp.Sdk.dll, is essentially the internal API that the PostSharp tool uses to perform the CIL manipulation necessary to apply aspects. This library is not supported and not documented (publicly). It is available only because a very small number of PostSharp users need it, and have the necessary expertise in CIL to use it.

Microsoft CCI

The Microsoft Common Compiler Infrastructure (CCI) is a set of tools from Microsoft that provide you with the ability to analyze and modify .NET assemblies. These projects are available on CodePlex, but the documentation hasn’t been updated in about two years (at the time of writing this book). Other metaprogramming/compiler-related projects such as Phoenix and Roslyn have also been created by Microsoft, but these are tangentially related to AOP.

One last note about CIL manipulation in general: its functionality is not limited to AOP and can be used for other tasks. For instance, NCover, a test coverage tool for .NET, uses CIL manipulation to do its instrumentation.

A.2. Runtime AOP tools

Runtime AOP tools create decorator/proxy classes dynamically at runtime. These classes are built by examining the signature of classes/interfaces along with an interception aspect that you’ve written, then generate a decorator class. Typically, these tools are part of IoC containers, as such containers allow you to use these generated classes transparently.

My goal in this appendix isn’t to comprehensively document and explore these IoC tools, but to show a basic demonstration of their interception capabilities. If you want to learn more about IoC, Dependency Inversion, and DI, I recommend picking up Dependency Injection in .NET by Mark Seeman (Manning, 2011).

A.2.1. Castle Windsor/DynamicProxy

Castle DynamicProxy is the name of the AOP tool that was originally created to work with Castle Windsor (an IoC tool). Castle is a project with a collection of frameworks and tools for building enterprise applications in .NET. I’ve shown you several examples throughout the book of Castle DynamicProxy with StructureMap. The next listing shows how you might use it with Castle Windsor (which isn’t remarkably different from using it with StructureMap, except that there is no need for a ProxyHelper class). The listing is a Console application; I’ve installed Castle Windsor with NuGet (Install-Package Castle.Windsor), which will install Castle.Core automatically.

Listing A.5. A basic Castle Windsor and DynamicProxy example

The entire Castle project umbrella—including Windsor, DynamicProxy, and MonoRail—has been one of the cornerstones of open source tools and frameworks for .NET since 2004. It is a popular and widely used set of tools, with a very active support and development community.

A.2.2. StructureMap

I used StructureMap throughout this book, and its EnrichWith functionality combined with Castle DynamicProxy has been covered. It’s certainly possible to use other AOP tools as well. But StructureMap does not contain any AOP capabilities itself. To quote the StructureMap documentation: “StructureMap will never include its own Aspect Oriented Programming model (the world does not need a new one).”

However, StructureMap does have its own interception capability. Its unique approach to interception is worth discussing in this appendix. StructureMap intercepts the object itself, instead of generating a decorator class, and allows you to manipulate the object. You do this by implementing the InstanceInterceptor interface, as shown in the next listing. This interface contains one method—Process—that receives the object as an argument, and returns the object, giving you a chance to manipulate, examine, or wrap the object.

Listing A.6. StructureMap interception

The console output is different than the other example in this appendix, because it is intercepting an object instead of method call(s):

You could also use Castle DynamicProxy within an InstanceInterceptor as an alternative to using a ProxyHelper class. I’ve found that it takes roughly the same amount of effort, depending on how heavy your usage of aspects is, whether custom conventions are being used, and so on.

A.2.3. Unity

The Unity Interception Extension (installed with NuGet with Install-Package Unity.Interception) is a component that is an extension of Unity (also known as the Unity Application Block). This component gives AOP interception capabilities to the core Unity functionality. Unity is an IoC container created by Microsoft with an emphasis on configurability and extension for building enterprise software. With Unity, aspects implement the IInterceptionBehavior interface. This interface has an Invoke method that is analogous to Castle DynamicProxy’s Intercept method.

There are two other members of this interface. GetRequiredInterfaces returns a list of interfaces that you want the dynamically created proxy object to implement (INotifyPropertyChanged, for instance, would be a good candidate for this). WillExecute is for optimization: if it returns false, then the interceptor will be skipped. The aspect in this listing does not use these capabilities.

Listing A.7. Unity interception example

The output, once again to Console, is the same as other examples in this appendix:

The Unity framework is both open source and backed by Microsoft, and thus it is widely used. It is still under active development, with a .NET 4.5 preview available at the time of writing.

A.2.4. Spring.NET

Spring.NET is a framework based on the popular Spring framework for Java. It contains a number of features for building enterprise applications (much like Castle Windsor), including Spring.Core (DI) and Spring.Aop (runtime AOP). Spring.NET tends to use XML for configuration of everything, so that’s what I’m going to use in this appendix, but Spring.CodeConfig allows you to configure in C# instead of XML if you wish.

Install Spring’s AOP functionality with NuGet (Install-Package Spring.Aop). This listing shows an aspect that implements the IMethodInterceptor interface, which just has one member: Invoke.

Listing A.8. Spring.NET example

In a Console project, the Spring configuration will be in app.config, as in the next listing. In an ASP.NET project, it would be in Web.config instead.

Listing A.9. Spring.NET configuration

Besides interception aspects, Spring.NET has boundary aspects (IMethodBeforeAdvice, IAfterReturningAdvice, and IThrowsAdvice). Beyond the simple mapping in this configuration, Spring.NET also has more complex configuration options, including regular expressions and dynamic pointcuts (akin to attribute multicasting as seen with PostSharp in chapter 8).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset