Friday, April 29, 2011

Aspect-Oriented Programming

The inherent limitations of the OO paradigm were identified quite a few years ago, not many years after the introduction of OOP. However, today AOP still is not widely implemented even though everybody agrees on the benefits it produces. The main reason for such a limited adoption is essentially the lack of proper tools. We are pretty sure the day that AOP is (even only partially) supported by the .NET platform will represent a watershed in the history of AOP.
Wikipedia: Gregor Kiczales started and led the Xerox PARC team that eventually developed AspectJ

Cross-Cutting Concerns

AOP is about separating the implementation of cross-cutting concerns from the implementation of core concerns. For example, AOP is about separating a logger class from a task class so that multiple task classes can use the same logger and in different ways.
We have seen that dependency injection techniques allow you to inject—and quite easily, indeed—external dependencies in a class. A cross-cutting concern (for example, logging) can certainly be seen as an external dependency. So where's the problem?
Dependency injection requires up-front design or refactoring, which is not always entirely possible in a large project or during the update of a legacy system.
In AOP, you wrap up a cross-cutting concern in a new component called an aspect. An aspect is a reusable component that encapsulates the behavior that multiple classes in your project require.

Processing Aspects

In a classic OOP scenario, your project is made of a number of source files, each implementing one or more classes, including those representing a cross-cutting concern such as logging.
In an AOP scenario, on the other hand, aspects are not directly processed by the compiler. Aspects are in some way merged into the regular source code up to the point of producing code that can be processed by the compiler. If you are inclined to employ AspectJ, you use the Java programming language to write your classes and the AspectJ language to write aspects. AspectJ supports a custom syntax through which you indicate the expected behavior for the aspect. For example, a logging aspect might specify that it will log before and after a certain method is invoked and will validate input data, throwing an exception in case of invalid data.

In other words, an aspect describes a piece of standard and reusable code that you might want to inject in existing classes without touching the source code of these classes.

In the AspectJ jargon, the weaver is a sort of preprocessor that takes aspects and weaves their content with classes. It produces output that the compiler can render to an executable.

In other AOP-like frameworks, you might not find an explicit weaver tool. However, in any case, the content of an aspect is always processed by the framework and results in some form of code injection. This is radically different from dependency injection. We mean that the code declared in an aspect will be invoked at some specific points in the body of classes that require that aspect.

Before we discuss an example in .NET, we need to introduce a few specific terms and clarify their intended meaning. These concepts and terms come from the original definition of AOP. We suggest that you do not try to map them literally to a specific AOP framework. We suggest, instead, that you try to understand the concepts—the pillars of AOP—and then use this knowledge to better and more quickly understand the details of a particular framework.

Inside AOP Aspects


As mentioned, an aspect is the implementation of a cross-cutting concern. In the definition of an aspect, you need to specify advice to apply at specific join points.

A join point represents a point in the class that requires the aspect. It can be the invocation of a method, the body of a method or the getter/setter of a property, or an exception handler. In general, a join point indicates the point where you want to inject the aspect's code.

A pointcut represents a collection of join points. In AspectJ, pointcuts are defined by criteria using method names and wildcards. A sample pointcut might indicate that you group all calls to methods whose name begins with Get.

An advice refers to the code to inject in the target class. The code can be injected before, after, and around the join point. An advice is associated with a pointcut.
Here's a quick example of an aspect defined using AspectJ:
public aspect MyAspect
{
// Define a pointcut matched by all methods in the application whose name begins with
// Get and accepting no arguments. (There are many other ways to define criteria.)
public pointcut allGetMethods ():
call (* Get*() );

// Define an advice to run before any join points that matches the specified pointcut.
before(): allGetMethods()
{
// Do your cross-cutting concern stuff here
// for example, log about the method being executed
.
.
.
}
}
The weaver processes the aspect along with the source code (regular class-based source code) and generates raw material for the compiler. The code actually compiled ensures that an advice is invoked automatically by the AOP runtime whenever the execution flow reaches a join point in the matching pointcut.


AOP can be implemented in dot net using the Microsoft's Policy Injection Application Block in Enterprise Library 3.0 and higher. You can check it on MSDN Magazine or at Programming Help


Hoping that this topic has brought to you a wider vision about AOP, stay tuned for some examples of implementing AOP in Dot Net 4.0

No comments: