I think what I need is something the .net folks call "transparent dynamic proxy", but all the implementations I've seen this far (Castle DynamicProxy, Spring.NET AOP, etc) require me to do at least one of these:
- Declare intercepted method as virtual
- Wrap class and create instances of the wrapper instead of wrapped class
- Change inheritance or implement interfaces
Obviously, if both caller and callee are nonvirtual and from thirdy-party closed source libraries, which is the case, there is nothing I can do.
If C# were a dynamic language like Python I would do something like this:
foo = ThirdyPartyLibA.Foo()
def interceptor(self, *args, **kwargs):
do_something_before(self, *args, **kwargs)
result = ThirdyPartyLibB.Bar.intercepted(self, *args, **kwargs)
do_something_after(self, result, *args, **kwargs)
return result
foo.bar.intercepted = interceptor # bar is an instance of ThirdyPartyLibB.Bar
foo.do_its_job() # Foo.do_its_job calls Bar.intercepted
I need this to change a bad behavior of ThirdyPartyLibA.Foo while interacting with ThirdyPartyLibB.Bar. I know exactly what causes this behavior and exactly how to change Foo or Bar to fix this bug thanks to dissasemblers.
Some (very unlikely to work) ideas:
- Disassemble ThirdyPartyLibA, make changes in code and generate a compatible assembly (unlikely to work because it's a strong-named assembly)
- Edit binary to make Foo's buggy methods virtual and change whatever is necessary for it to remain a valid assembly so I can use dynamic proxies (very unlikely to work, also because of the same reason as the idea above)
- Find a transparent dynamic proxy implementation that fits (I think there is none based on this forum thread: http://www.pcreview.co.uk/forums/overriding-non-virtual-methods-using-il-and-reflection-emit-t2605695.html)
- Contact the company that created the library (they don't support the product anymore)
- Stop using the library or use an alternative (impossible, since it's part of the runtime of a RAD IDE that we are tied to because there is a HUGE amount of code written using the IDE own language)
- Control the calls to the problematic methods to avoid the bug (we already did this but it didn't solve the problem completely)
Do you have any other idea?
PS: Sorry for my bad english. Also, sorry for my Python. This code is here just to illustrate what I need, don't take it as a recipe because it's horrible.