Aspect Oriented Programming using .NET

Page 2 of 3
  1. What is AOP?
  2. Language Support for AOP
  3. AOP in C#

Language Support for AOP

AOP support has to be built in to the language and/or framework because it is based on method call interception. Whenever a methods is called the framework needs to provide a stub to call some other piece of code. Though .NET CLR has this capability, but it is intrusive as you need an object to extend from MarshalByRefObject  or ContextBoundObject to allow method-interception. This is a serious limitation because each class needs to be written so that it supports AOP. Many AOP languages or language-extensions get around this limitation by using various techniques. The techniques generally fall into two broad categories runtime or dynamic weaving, compile-time or static weaving.

Aspect# is AOP language which uses static compile time weaving. It uses its own proxy (and not CLR's proxy) called DynamicProxy. DynamicProxy is generated compile time and works differently while proxying interfaces (generates dynamic class and delegates method calls to the target of invocation) and proxying classes (generates stub class that inherits from the target).

Aspect# provides syntax to define point-cut and call method-interceptors or advice for them. It's done as follows 

import YourCompany.CMS.ContentProviders in YourCompanyAssembly
import YourCompany.CMS.Aop.Interceptors

aspect SecurityAspect for RSSContentProvider
include Mixins.SecurityResourceImpl in MyMixinsAssembly

pointcut method(* MyMethod(*))
end public class TracingInterceptor : IMethodInterceptor
public object Invoke(IMethodInvocation invocation) { // Trace using information from IMethodInvocation // like Method, MethodInvocationTarget return invocation.Proceed(); } }

The important bits are marked in bold. The first block is the point-cut in a Ruby like syntax which specifies all methods with the name MyMethod to be included in the join-points.  The second block is the interceptor (advice) TracingInterceptor. The TracingInterceptor is a class that has to implement the IMethodInterceptor. It can call invocation.Proceed to continue with the method invocation once it's done with the tracing. So whenever the MyMethod is called TracingInterceptor.Invoke gets called.

Other languages like AspectDNG (.NET based AOP language-extension) accomplishes this using something called IL weaving. In this the target or base-code is coded in any language that can be compiled into MSIL like C#, VB.NET, J#. So the target code can look like

using System;
public class MyClass {
public int ProcessString(String s, out string outStr) {
// ...

There is no special code or any type of modification needed on the base-code as evident from above which is plain-vanilla C# code. The aspect code is written as follows which can also be C# code and needs some additional assembly reference and attribute decoration for AspectDNG to pick them up

  using DotNetGuru.AspectDNG.MetaAspects;
using DotNetGuru.AspectDNG.Joinpoints;
using System; public class AspectsSample{ [AroundCall("* MyClass::ProcessString(*)")]
public static object YourMethodCallInterceptor(JoinPoint jp) { Console.WriteLine("Code before calls to '.. MyClass.ProcessString(..)'"); object result = jp.Proceed(); Console.WriteLine("Code after calls to '.. MyClass.ProcessString(..)'"); return result; } }

Here point-cut is specified using attributes like AroundCall, AroundBody. Both the base-code and the aspect code are separately compiled into different assemblies using respective compilers like csc into Target.exe and aspect.dll. Then the aspectdng.exe tool can be used which uses reflection to reach to the attribute in the aspect code to weave call to them so that a new assembly called Target-weaved.exe is created. In target-weaved.exe AspectDNG directly puts in calls to the aspects around the target code by inserting/replacing IL code wherever required.

There are some AOP languages like Encase which apply the aspects at run time. These languages use AOP frameworks which reads in configuration files for point-cuts and at runtime generate proxy classes that intercept calls, allows advice of the aspect to execute first and then invokes the actual target. The benefit is that there is not edit-compile cycle but it faces performance issues.

You might also like...




Our tools

