Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Aspect Oriented Programming 101

3.88/5 (7 votes)
3 Jan 2010CPOL4 min read 35.8K   212  
What is Aspect oriented programming and where do I use it?

Introduction

This article deals with the fundamentals of aspect oriented programming. It is a level 101 discussion. In this article, we describe the essential concepts of AOP and its need in a layered architecture environment. Finally, we detail out a logging framework using Enterprise library which is developed using AOP.

Audience

The primary audience of this article are architects and designers having an understanding of layered architecture and its benefits.

Layered Architecture and Separation of Concern

The diagram given below shows a layered architecture of a typical .NET web application.

Image 1

It teaches us that there are many layers. Each layer has a purpose, need, contract and is a shield from underlying and layers above it.

The Data access layer has the purpose of how to store and retrieve data. Its need is to access data, it has a contract defined by data access methods, it shields application from changes from database and DB from business rules. Typically a data access layer will not even be aware of how the UI works.

What About Concerns Which Can't be Separated?

There exist a whole bunch of concerns which can't be separated. These are cross cutting concerns. A change in these means a change across the application.

Image 2

When we write code to access DB we only write in data access layer, however code to write trace logging is written across the application. If due to some reason, we have been tracing only methods names and one fine day plan to start tracing method input parameters and return type code changes must be made across the application.

Unfortunately the cross cutting concerns are the ones which end up being least thought through in the application, think about how often in a design do we think about our exception hierarchy?

What is AOP

AOP or Aspect oriented programming is a mechanism using which cross cutting concerns can be developed separately and then combined with executing code of different layers. As it is obvious, we can have two types of AOP frameworks, one which hook up to the code at run time, others which modify the code at design time.

I find the term aspect oriented programming a bit confusing and would rather call it "Entangled Concern Separation Pattern".

Some Nice AOP Frameworks in .NET

There are a whole bunch of AOP frameworks that exist. In this discussion, we will use PostSharp (http://www.postsharp.org/aop-net/overview). This framework modifies the assemblies at compile time.

PostSharp is very detailed well organised framework and one article will not do justice to it. In this article, we will explore some very basic examples using a logging framework built using PostSharp and Microsoft enterprise library,

PostSharp allows aspects of a class to be modified. Let us look at the OnMethodBoundaryAspect class, which can be overridden by the end user. This class provides various Hooks:

  • OnEntry - Called when a method is entered
  • OnExit - When a method exits
  • OnException - When a method has an exception

and others....

We can override these methods and do logging in these.

C#
class OnMyExceptionAspect : OnMethodBoundaryAspect
{
}

We can override OnEntry:

C#
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
base.OnEntry(eventArgs);
Console.WriteLine(String.Format("Entering method {0}", eventArgs.Method.Name));
object[] methodArguments = eventArgs.GetReadOnlyArgumentArray();
foreach (object methodArgument in methodArguments)
{
Console.WriteLine(String.Format("The method argument is {0}", methodArgument));
}
}

As we can see in this sample code, using MethodExecutionEventArgs class is being used to find details of the method and write the details to console. You may find this code in AOPPostSharp_SampleCodeForConsoleLogging.zip.

You will have to install PostSharp and Visual Studio 2005 for this sample.

Hooking into the Classes- How to Compile?

To allow this information to be spit into the DLL during compilation, we have to modify the assembly information and the Microsoft build file.

The assembly information is modified with the inputs:

C#
[assembly: AOPSample.OnMyExceptionAspect(AttributeTargetAssemblies = 
	"AOPPostSharp", AttributeTargetTypes = "AOPSample.Program")]

which tells what AOP class will be used.

It is in the compilation where all the magic happens to add up some information into the .csproj file.

XML
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="C:\Program Files\PostSharp 1.5\PostSharp-1.5.targets" />

This is essentially a Microsoft build file where we are adding some information around how compilation will be done.

Looking at the Original Code and Decompiled Code

The code snippet before compilation is:
C#
static void Main(string[] args)
{
MethodWithNoException(10, 5);
try
{
And after compilation on decompiling with reflector 
MethodExecutionEventArgs ~laosEventArgs~2; 
try 
{ 
object[] ~arguments~1 = new object[] { args }; 
~laosEventArgs~2 = new MethodExecutionEventArgs
	(<>AspectsImplementationDetails_1.~targetMethod~4, null, ~arguments~1); 
<>AspectsImplementationDetails_1.AOPSample.OnMyExceptionAspect~4.
	OnEntry(~laosEventArgs~2); 
if (~laosEventArgs~2.FlowBehavior != FlowBehavior.Return) 
{ 
MethodWithNoException(10, 5); 
try 
{

On execution of the code, we see:

Image 3

which is a lot of tracing which we had not added which was added during compilation.

A Very Simple Logger Framework Example

Using the above studied concepts, we will now attempt to develop a simple logger which will use AOP to log information using enterprise library.

In this discussion, we will assume that the audience is familiar with the Microsoft enterprise library.

The Logger Framework

C#
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
base.OnEntry(eventArgs);
StringBuilder message = new StringBuilder(String.Format
	("Entering method {0}", eventArgs.Method.Name));
object[] methodArguments = eventArgs.GetReadOnlyArgumentArray();
foreach (object methodArgument in methodArguments)
{
message.Append(String.Format("The method argument is {0}", methodArgument));
}
LogDebug(message);
}
private static void LogDebug(string message)
{
LogEntry logEntry = new LogEntry();
logEntry.EventId = 100;
logEntry.Priority = 2;
logEntry.Message = message;
logEntry.Categories.Add("Trace");
Logger.Write(logEntry);
}

As you can see, in the code we have not done anything very clever, all the good stuff is already being done by the AOP framework and all we did was write a bunch of lines to log using a very nice framework.

This is not a very hot shot framework and is even bad enough to have hard coding, but it brings out the idea.

I intend to come up with a proper exception handling framework with a decent design in a few days to elaborate how good this tool can be.

History

  • 4th January, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)