Wednesday, September 10, 2008

[AOP] Aspect-Oriented Programming part 1

I've always been interested in AOP (Aspect Oriented Programming). I've spent a lot of time trying to figure out Policy Injection Application Block in Enterprise Library 3 and Spring Framework. Both frameworks made AOP a lot more accessible than it was before. Offcourse PIAB has its downsize, not being compatible with ObjectBuilder so AOP and DI with entlib is a no-go.

The only thing the .NET framework missed was a compile time weaver. PIAB and Spring are runtime weavers, which basically means your code knows it's using AOP. For example a logging advice:

Basic .NET:
public class MyClass
{
public void DoSomething()
{
MessageLogging.Write(“Starting method DoSomething”);
// Run code

MessageLogging.Write(“End method DoSomething”);
}
}


class Program
{
static void Main(string[] args)
{
MyClass mine = new MyClass();
mine.DoSomething();
}
}

When you're using Spring it should look something like this:


public class MyClass
{
public void DoSomething()
{
// run code
}
}


// spring advice:
public class LoggingAdvice : IMethodInterceptor
{
public object invoke(IMethodInvocation invocation)
{
MessageLogging.Write(“Starting method DoSomething”);
Object returnvalue = invocation.Proceed();
MessageLogging.Write(“End method DoSomething”);
return returnValue;
}
}

class Program
{
static void Main(string[] args)
{
ProxyFactory factory = new ProxyFactory(new MyClass());
Factory.AddAdvice(new LoggingAdvice());
((MyClass)factory.GetProxy()).DoSomething();
}
}


The crosscutting concern (logging) is seperated from the method. The method DoSomehting isn't aware of the logging code. But the code using the method is well aware of the use of AOP (creating a proxyfactory). One advantage is that as a developer you will see the use of AOP. (But the code isn't getting any better, in my opinion).

PostSharp is a compile time weaver, which means that postsharp will rewrite the MSIL, PostSharp is a post-compiler. PostSharp will inject itself in the build process and transforms or analyzes the program after its compiled. PostSharp is integrated in the MSBuild Proces and already has some plugins available:

- PostSharp Laos (for easily writing aspects)
- Software Transactional Memory (for using In-memory datastructures)
- Entity Framework Bindings
- PostSharp4Entlib (extend PIAB with PostSharp)
- PostSharp4Spring (integrate PostSharp with the Spring Framework)
- Log4PostSharp (Custom attribute for Log4Net)


Because PostSharp is a compile time weaver, I don't have to use a proxyfactory. I just have to create an aspect and put it above my method:

public class MyClass
{
[LoggingAspect ]
public void DoSomething()
{
// run code

}
}

class Program
{
static void Main(string[] args)
{
MyClass mine = new MyClass();
mine.DoSomething();
}
}

[Serializable]
public class LoggingAspect : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
MessageLogging.Write("Method: " + eventArgs.Delegate.Method + " is called");
eventArgs.Delegate.DynamicInvoke(eventArgs.GetArguments());
MessageLogging.Write("Method call ended");
}
}


My calling code and method looks clean and mean, just the way I like it :).

No comments:

Post a Comment