Ayende @ Rahien

Refunds available at head office

7 Approaches for AOP in .Net

Here are all the ways that I can think of to add AOP to your application. This mostly focus on the interception side of things, because once you have that, everything else it just details.

Approach Advantages Disadvantages
Remoting Proxies Easy to implement, because of the .Net framework support Somewhat heavy weight
Can only be used on interfaces or MarshalByRefObjects
Deriving from ContextBoundObject Easiest to implement
Native support for call interception
Very costly in terms of performance
Compile-time subclassing
( Rhino Proxy )
Easiest to understand
Interfaces or virtual methods only
Runtime subclassing
( Castle Dynamic Proxy )
Easiest to understand
Very flexible
Complex implementation (but already exists)
Interfaces or virtual methods only
Hooking into the profiler API
( Type Mock )
Extremely powerful Performance?
Complex implementation (COM API, require separate runner, etc)
Compile time IL-weaving
( Post Sharp / Cecil )
Very powerful
Good performance
Very hard to implement
Runtime IL-weaving
( Post Sharp / Cecil )
Very powerful
Good performance
Very hard to implement

Comments

Roy Osherove
07/02/2007 04:17 AM by
Roy Osherove

Looking at the code for Rhinomocks, I was pretty sure you were using Dyanmic Proxy to create the mocks (at runtime). You're not?

Mark Monster
07/02/2007 07:05 AM by
Mark Monster

Hmm, almost a year ago I was looking into AOP. This was just after reading a book about AOP in Java. I found out some people also find Declarative Programming using Attributes a way of Aspect Oriented Programming. I'm not sure about this. Yes we are centralizing our concerns, but we are coupling them tightly with our objects.

Jb Evain
07/02/2007 07:41 AM by
Jb Evain

You can have a look at AspectDNG if you want to have a look at a static weaver that is already implemented.

http://aspectdng.tigris.org

Stefan Wenig
07/02/2007 08:33 AM by
Stefan Wenig

I wrote an interception infrastructure using remoting proxies/ContextBoundObject a few years ago, and here's why I think it doesn't fly:

  • You can't intercept calls on 'this' (actually, I found a way, but it involved native x86 assembler, native thread-static flags that decide whether to intercept or to do the actual call, broke the CLR promise that 'this' would never be a proxy, made it impossible for the debugger to step-into, and all in all was just insanely complex. I dropped it)

However, AOP is very incomplete if you can only intercept method calls on object boundaries.

  • The performance penality was a factor of about 1000 compared to plain virtual calls, although I removed the whole remoting infrastructure and worked with a plain transparent/real proxy pair. It still does involve remoting though. Now a plain call is cheap, and 1000 x cheap might not amount to much if you call a method that actually does stuff. Although that stuff is calling other intercepted methods, that is. So for a general purpose interception infrastructure this is far to heavy. I was very surprised when I recently learned that EntLib is going down this path...

Using the profiler API is probably the most fragile and unportable here. So this gives us a choice of either subclassing or weaving. I suspect the biggest problem with weaving is binary compatibility. I wonder how this is dealt with when weaving strong-named assemblies.

The major problems of sublcassing are:

  • Does not work for non-virtual methods, like you said. Given the importance that AOP and interception are gaining, I think something should be done about it. I tried to talk to Eric Lippert about it, but unfortunately he sometimes just doesn't answer...

http://blogs.msdn.com/ericlippert/archive/2007/06/14/calling-static-methods-on-type-variables-is-illegal-part-one.aspx (second comment)

  • Can't be used if objects are created with 'new'. Hey, we really need a way to overload 'new' (C#) or 'newobj' (IL)! Or at least some discipline to use factories for object creation. This is an area where code written by Microsoft (or generated by MS-tools) usually looks like it was built by amateurs. Really, this has to stop.

You could add that weaving gives you more power to hook right into the body of an existing method, but depending on your point of view, that is not necessarily an advantage. Subclassing constrains you to the interfaces that the author of a class defined, so your aspects should not break if that class changes (or anything derived from that class could break, so at least there is no new category of breaking changes that the author might not be aware of). I think even with AOP you should treat other people's methods as black boxes, unless you use AOP for patching.

A'braham Barakhyahu
07/04/2007 10:19 PM by
A'braham Barakhyahu

I would like to see this expanded to see what issues each one address.

John Rusk
07/08/2007 11:33 AM by
John Rusk

Here is one more approach to AOP: http://dotnet.agilekiwi.com/blog/2007/07/claytons-interception.html

John Rusk
07/08/2007 11:33 AM by
John Rusk

Here is one more approach to AOP: http://dotnet.agilekiwi.com/blog/2007/07/claytons-interception.html

Comments have been closed on this topic.