I am finding cooler and cooler stuff to achieve using the CThru Engine.
A few hours ago I suddenly thought : “CThru intercepts all calls in the system. what happens if they are calls to methods that don’t exist?”
Logically this led me to:
- VB.NET supports late bound invocation (with option strict off – great for COM related stuff)
- other languages (like Ruby) have a feature called “MethodMissing” whereby you get an callback when a missing method is invoked in the system, so you can do whatever you want.
- Maybe we can have MethodMissing in VB.NET??
So I set out to achieve this.
A couple hours later, I can now do this:
Notice that “NonExistingMethod” really does not exist on the current type (nor does it have any extension methods).
I simply register to the MissingMethodCall event published by CThruEngine, so that I can now control its behavior.
And here’s how I handle the event:
If I execute “MyMethod” here’s the output:
Now, imagine the possibilities.. :)
How does it work? Well, in VB.NET, there’s a special class called “Microsoft.VisualBasic.CompilerServices.NewLateBinding” that has a method “LateCall” that gets called for all late bound method calls. Of course, it also returns a value. I simply (well, not quite) intercept the calls to it and before VB throws an exception, I can let the user of the event return whatever value they want from that method, and then I skip it’s actual call and return the value.
This will also work with late bound index calls, property values (set and get) and more.
CThru is an open source engine that sits on top of the Typemock Open-AOP hooks (part of the new 5.2.2 release).
To learn more about CThru and get the tests and source code, go here.
I’ve updated the implementation so that it is more like Ruby. If the class being called declares a method named “missing_method” that takes a MissingMethodArgs parameter, that method will be invoked automatically by the CThru engine, without needing to register to an event:
It’s also useful to consider that you can implement “missing_method” in C# based assemblies. As the C# types are called in a late bound manner from VB, it should work exactly the same. Given:
We can write this in VB: