简体   繁体   中英

Overriding method in DLL using reflection

I am not even sure if this is possible so apologies if not. I have googled quite extensively and not found what I am looking for.

Basically we have an application produced by a third party, which, to be perfectly blunt is rubbish. We have a particular issue and have managed to trace the problem using ILSpy to a method within a DLL. Obviously we don't have (nor are able to get) the source code and the company in question is unwilling to fix the problem in any reasonable timescales.

So, we've investigated various avenues of investigation and come up with nothing. I've been looking into seeing whether this can be done using reflection and this is pretty much the last hope we have of getting this to work. In a nutshell, what I would like to do is the following:

  • Create a simple class library with the same name as the existing DLL
  • Use reflection to import the methods from the existing DLL
  • Somehow override the method in question with my own, correct code
  • Rebuild the code, so I have a new DLL, containing 99% of the functionality of the existing DLL but with my override code providing the correct functionality.

I have found, during my investigations TypeBuilder.DefineMethodOverride and also a page from StackOverflow, which seems similar but not quite what I am looking for.

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

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

Any advice appreciated!

Andrew

Edit

The other possible idea I has was to produce a partial class containing the override function, but that didn't seem feasible either.

You can override the method only if it is virtual, and it doesn't matter whether you do it through reflection or statically. I would suggest using a decompiler (there are a lot of free ones available) and fixing the code in MSIL. Then you can generate a new assembly from the MSIL.

I think your first idea is good. If the third party class isn't sealed , you can derive from it, and add your own method, with a different name, to correct the behavior that is wrong. If you need it to be in 1 dll, you can use IlMerge .

If your third party class is sealed you can just have an instance of this third party class in your new class and call the methods when needed.

But you'll have to check that the method you want to "override" isn't called inside that library, because if it is this solution won't work...

It's not very clean, but it can be a temporary solution during the time the company that edits the library fixes the problem.

And when it's fixed you'd just have to rename the method you use, so it won't be time consuming.

From what you have described I would recommend modifying the original assembly. The process is essentially

  • Decompile the assembly into MSIL, C# or whatever language you so choose
  • Modify the decompiled assembly to include your changes
  • Recompile the assembly using the modified source

From what I can see Reflexil allows you to do just that, although it may require that you buy Resharper (I've not tried it myself)

Alternatively you can use ILDasm to decompile the entire assembly to a single file, modify the file and then recompile it using ILAsm

I know I'm coming in a bit late on this, but I'd agree with Charleh; if you've got a class that's not behaving well and isn't conducive to substitution, but at least declares its methods as virtual , then you're in luck. The following uses references to Castle.Core and Patterns :

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();

I've also taken the liberty of providing a running sample of this in LinqPad. It shows the difference between methods that allow interception ( virtual ones) and ones that don't. It also shows a useful way of trapping exceptions without all the code using Try.Do from Patterns .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM