Sunday, January 6, 2008

LinFu AOP, Reinvented

After four days of coding and refactoring, I've done it! I've managed to rewrite the original version of LinFu.AOP to address all of the issues that I mentioned in previous posts, and now I only need to write the MSBuild task and the command-line weaver before I can go ahead and start working on the CP article. I know that LinFu.AOP has been vaporware as of late, but I can guarantee you that this is definitely worth the wait.

Aside from the features that I mentioned earlier in this blog, LinFu.AOP will add some interesting features to the LinFu Framework, such as:

Even simpler Simple.IOC integration

With LinFu.AOP, you no longer have to even reference Simple.IOC.dll in your application to use the container. For example, instantiating an IDbConnection type from a SimpleContainer instance will be easy as:

IDbConnection myConnection = New.Instance;

...that's it! Behind the scenes, LinFu.AOP will actually intercept the call made to the following class:

public class New
{
public static T Instance
{
get { throw new NotImplementedException(); }
}
}

Now, believe it or not, the code listing above is the actual implementation of the New class. What I'm actually doing is using LinFu.AOP to redirect the request for an IDbConnection instance to an appropriate factory method (in this case, the Simple.IOC container). What makes this even more interesting is that it employs the same type of XCOPY-style configuration that you would expect from LinFu; it means that if you wanted to inject any more dependencies into the container, all you have to do is drop the new dependencies into the directories, and the container will rebuild itself and that dependency will be available in the next New.Instance call!

LinFu.DynamicProxy 'Submersion'

One of LinFu.DynamicProxy's weaknesses is that its interceptor instances can only be bound to an unsealed type with all of its public methods marked virtual. With LinFu.AOP, that limitation no longer applies.

LinFu.AOP allows LinFu.DynamicProxy interceptors to intercept methods and properties on type instances without even using the proxy generator itself. This means that when LinFu.AOP intercepts a method call done against a target type, there is no intermediate proxy doing the interception. LinFu.AOP rewrites the IL in your method body and redirects it to your interceptor, all at runtime. You can even reuse the old method implementation as if you were still using DynamicProxy.

One could even say that the inteceptor has 'submerged' itself into the type implementation because the interceptor can still intercept any method on any given type as if it were still attached to the proxy--however, what makes it 'submerged' is the fact that you're actually using the true object instance itself!

To take this concept even further, LinFu.AOP supports two levels of method interception: Class-Based, and Instance-Based.

This means that you can either intercept a particular method across all instances of a given type, OR you can actually customize the method replacement (or interceptor) based on the current instance that you're using. Think about that for a moment...

...and while you're thinking about that, I'm going to go back and polish this thing up. :)

5 comments:

  1. It doesn't bust my bubble at all.

    There are numerous AOP and DI frameworks out there aside from LinFu, and I won't lose much sleep if Spring has their own implementation of AOP. They certainly have their way of doing things, and I have my own ways, which I believe are much more simple.

    If they come up with something better than my own creation, well, then good for them. :)

    ReplyDelete
  2. Good to know.

    I haven't really delved into how Spring does theirs, but yours was the first one I came across with (in CodeProject) and I immediately wondered why these features were not included in .Net.

    Kudos for all your efforts. You really must love programming to devote so much into these features.

    Looking forward to more posts :)

    ReplyDelete
  3. Hey, out of curiosity, what are you using under the hood to manipulate IL?

    ReplyDelete
  4. I used Reflection.Emit in LinFu 1.0, and in LinFu 2.0, I've migrated all the Reflection.Emit code to Mono.Cecil.

    ReplyDelete

Ratings by outbrain