我认为我需要的是.net人称之为“透明动态代理”的东西,但我到目前为止看到的所有实现(Castle DynamicProxy,Spring.NET AOP等)都要求我至少做一个这些:
显然,如果调用者和被调用者都是非虚拟的,并且来自第三方封闭源库,那么我就无能为力。
如果C#是像Python这样的动态语言,我会做这样的事情:
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
我需要这个来改变ThirdyPartyLibA.Foo在与ThirdyPartyLibB.Bar交互时的不良行为。我确切知道导致这种行为的原因以及如何通过dissasemblers改变Foo或Bar以修复此错误。
一些(非常不可能工作)的想法:
你还有其他想法吗?
PS:抱歉我的英语不好。另外,对不起我的Python。这段代码只是为了说明我需要的东西,不要把它作为食谱,因为它太可怕了。
答案 0 :(得分:3)
包装库并使用ReSharper之类的工具查找库的所有用法并替换为包装类。您也可以利用这个机会来清理第三方库的可能糟糕的界面。
虽然TypeMock通常用作测试工具,但它允许您模拟所有内容。因为它将自身注入代码分析器,所以你可以模拟的东西包括类的私有和静态成员。作为奖励,任何被覆盖的方法都不需要是虚拟的,因此您可以通过这种方式拦截调用。
我建议你使用解决方案1.包装器很容易理解,它会为你提供一个真正改进代码的好机会。我甚至建议您将第三方库包装为一般规则。
答案 1 :(得分:1)
如果Bar是静态的,您可以使用Moles来绕过方法调用。请注意,这是一种非常严厉的方法来修复错误,实际上不建议用于生产代码,但如果你绝望的话,这是一个选择。