使用反射在DLL中覆盖方法

时间:2013-06-18 13:54:48

标签: c# reflection dll

我甚至不确定这是否可能,所以如果没有道歉。我搜索的内容相当广泛,没有找到我要找的东西。

基本上我们有一个由第三方制作的应用程序,完全生硬是垃圾。我们有一个特定的问题,并设法使用ILSpy跟踪DLL中的方法的问题。显然,我们没有(也无法获得)源代码,并且有问题的公司不愿意在任何合理的时间范围内解决问题。

因此,我们调查了各种调查途径并且没有提出任何建议。我一直在研究是否可以使用反射完成这一点,这几乎是我们让这个工作的最后希望。简而言之,我想做的是:

  • 创建一个与现有DLL同名的简单类库
  • 使用反射从现有DLL导入方法
  • 以某种方式使用我自己的正确代码覆盖有问题的方法
  • 重建代码,所以我有一个新的DLL,包含现有DLL的99%的功能,但我的覆盖代码提供了正确的功能。

我在调查过程中发现了TypeBuilder.DefineMethodOverride以及StackOverflow中的一个页面,它看起来很相似,但并不是我想要的。

http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx

Is there a way to "override" a method with reflection?

任何建议表示赞赏!

安德鲁

修改

我的另一个可能的想法是生成一个包含覆盖函数的分部类,但这似乎也不可行。

4 个答案:

答案 0 :(得分:6)

只有当它是虚拟方法时才能覆盖该方法,无论是通过反射还是静态方式都可以。我建议使用反编译器(有很多免费的可用)并在MSIL中修复代码。然后,您可以从MSIL生成新程序集。

答案 1 :(得分:0)

我认为你的第一个想法是好的。 如果第三方类不是sealed,您可以从中派生,并添加您自己的方法,使用不同的名称来纠正错误的行为。 如果您需要它在1 dll中,则可以使用IlMerge

如果您的第三方课程已被密封,您可以在新课程中拥有此第三方课程的实例,并在需要时调用这些方法。

但是你必须检查你想要“覆盖”的方法是不是在那个库中调用的,因为如果是这个解决方案将不起作用......

它不是很干净,但在编辑库的公司解决问题时,它可以是一个临时解决方案。

当它被修复时,你只需要重命名你使用的方法,所以它不会耗费时间。

答案 2 :(得分:0)

根据您所描述的内容,我建议您修改原始装配体。这个过程基本上是

  • 将程序集反编译为MSIL,C#或您选择的任何语言
  • 修改反编译的程序集以包含您的更改
  • 使用修改后的源
  • 重新编译程序集

从我所看到的Reflexil允许你做到这一点,虽然它可能要求你购买Resharper(我自己没试过)

或者,您可以使用ILDasm将整个程序集反编译为单个文件,修改文件,然后使用ILAsm

重新编译它

答案 3 :(得分:0)

我知道我迟到了,但我同意查理的意见;如果你的课程表现不佳并且不利于替换,但至少将其方法声明为virtual,那么你很幸运。以下内容使用对Castle.CorePatterns的引用:

var interceptor = new DelegateInterceptor(proceed: call => 
{
  if(ShouldCallProceed(call)) call.Proceed();
  else AlternativeLogic();
});

var generator = new ProxyGenerator();
var proxy = generator.CreateClassProxy<UncooperativeType>(interceptor);

proxy.RubbishMethod();

我也冒昧地在LinqPad中提供a running sample of this。它显示了允许拦截的方法(virtual个)和不允许拦截的方法之间的区别。它还显示了使用Try.Do中的Patterns来捕获异常而不使用所有代码的有用方法。