AOP in .NET
By Matthew Groves
Aspect-oriented programming is a technique that is complementary to object-oriented programming (OOP). The goal of AOP is to reduce repetitive, boilerplate code. This article, based on AOP in .NET, walks you through a very basic "Hello, World" example of using AOP in .NET. He breaks apart that example and identifies the individual puzzle pieces and how they fit together into something called an "aspect."
“Hello, World” Aspect
If you’ve never done aspects, we’ll give you a taste of what’s in store. Don’t worry if you don’t fully understand what’s going on just yet. Follow along just to get your feet wet. I’ll be using Visual Studio 2010 and PostSharp. Visual Studio Express (which is a free download) should work too. I’m also using NuGet, which is a great package manager tool for .NET that integrates with Visual Studio. If you’ve never used NuGet, you should definitely take a few minutes to check it out at NuGet.org and install it: it will make your life as a .NET developer much easier.
Start by selecting File>New Project and then Console Application. Call it whatever you want, but I’m calling mine "HelloWorld". You should be looking at an empty console project like so:
class Program { static void Main(string[] args) { } }
Next, install PostSharp with NuGet. NuGet can work from a PowerShell command-line within Visual Studio, called Package Manager Console. To install PostSharp via the Package Manager Console, just use the Install-Package command.
Listing 1 Installing PostSharp with NuGet PowerShell console
PM> Install-Package postsharp Successfully installed 'PostSharp 2.1.6.17'. Successfully added 'PostSharp 2.1.6.17' to HelloWorld.
Alternatively, you can do it via the Visual Studio UI by first right-clicking on References in Solution Explorer.
Figure 1 Starting NuGet with the UI
Select Online, search for PostSharp, and click Install.
Figure 2 Search for PostSharp and install with NuGet UI
You may get a PostSharp message that asks you about licensing. Accept the free trial and continue. The Starter Edition is free for commercial use, so you can use it for free at your job too. Now that PostSharp is installed, you can close out of the NuGet dialog. In Solution Explorer under References, you should see a new PostSharp reference added to your project.
Now you’re ready to start writing your first aspect.
Create a class with one simple method that just writes to Console. Mine looks like this:
public class MyClass { public void MyMethod() { Console.WriteLine("Hello, world!"); } }
Instantiate this inside of the Main method,and call the method. Here’s what the Program class should look like now:
class Program { static void Main(string[] args) { var myObject = new MyClass(); myObject.MyMethod(); } }
Execute that program now (F5 or CTRL+F5 in Visual Studio), and your output should look like this:
We’re not really pushing the limits of innovation just yet, but hang in there!
Now, create a new class that inherits from OnMethodBoundaryAspect, which is a base class in the PostSharp namespace. Something like this:
Listing 2 The first step in using the PostSharp API – derive from OnMethodBoundaryAspect
[Serializable] public class MyAspect : OnMethodBoundaryAspect { }
PostSharp requires aspect classes to be serializable (this is because PostSharp instantiates aspects at compile time, so they can be persisted between compile time and run time).
Congratulations, you just wrote an aspect, even though it doesn’t do anything yet. Like the name implies, this aspect allows you to insert code on the boundaries of a method. Let’s make an aspect that inserts code before and after a method gets called. Start by overriding the OnEntry method. Inside of that method, write something to Console, like this:
Listing 3 Override the OnEntry method to add some functionality
[Serializable] public class MyAspect : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { Console.WriteLine("Before the method"); } }
Notice the MethodExecutionArgs parameter. It’s there to give information and context about the method being bounded. We won’t use it in this simple example, but argument objects like that are almost always used in a real aspect. Create another override, but, this time, override OnExit.
Listing 4 Override the OnExit to add more functionality
[Serializable] public class MyAspect : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { Console.WriteLine("Before the method"); } public override void OnExit(MethodExecutionArgs args) { Console.WriteLine("After the method"); } }
Now you have written an aspect that will write to Console before and after a method. But, which method? The most basic way to tell PostSharp which method (or methods) to apply this aspect to is to use the aspect as an attribute on the method. For instance, to put it on the boundaries of the earlier "Hello, World" method, just use it on the method like so:
Listing 5 Apply the aspect to a method by using an attribute
public class MyClass { [MyAspect] public void MyMethod() { Console.WriteLine("Hello, world!"); } }
Now, run the application again (F5 or CTRL+F5). You should see an output like this:
Figure 4 Output with MyAspect applied
That’s it. You’ve now written an aspect and told PostSharp where to use that aspect. This example may not seem that impressive, but notice that you were able to put code around the method without making MyMethod any changes to MyMethod itself. Yeah, you did have to add that [MyAspect] attribute, but there are more efficient and/or centralized ways of applying PostSharp aspects.
Here are some other Manning titles you might be interested in:
Spring in Action, Third Edition Craig Walls |
|
Willie Wheeler, John Wheeler, and Joshua White |
|
Mark Fisher, Jonas Partner, Marius Bogoevici, and Iwein Fuld |