如何在C#中拦截方法调用

7
我希望在调用C#中的第三方代码时拦截并注入自定义代码。我正在使用一个外部库(AutoIt)进行GUI自动化。该AutoIt dll没有提供源代码。
该框架执行的所有操作都是从单个类(AutoItClass)执行的,该类提供对所有方法的访问。我希望在调用此类的方法时能够注入自定义代码,这是否可能?例如:
1. 从调用的方法中记录一些信息。 2. 在方法内执行任何其他操作(等待X秒)。
这可以通过继承该类并覆盖其所有方法(这是必须的,因为这是一个COM对象)来非常简单地实现,但这不是首选方式。任何评论都将有所帮助!

2
这被称为面向切面编程(或AOP)--目前许多编程语言都没有很好的支持。你需要编译器支持来注入你的调用。 - Stephen Chung
2个回答

5

我不建议使用继承,你可以在这里使用组合。创建自己的类,其中包含相同的方法 - 或者实际上只包含你感兴趣的那些方法 - 并通过它进行委托。这样,你就可以确保不会意外“遗漏”任何方法,因为你没有实现的任何东西都不能通过代码库中的其他部分调用......前提是你确保代码的其余部分不引用原始的库类。


1
这仍然涉及大量的手动工作。难道没有任何框架可以允许这样说吗:WhenCalled(autoit.ClickButton, PerformThisMethod); - lysergic-acid
@liortal:你可以很容易地自动生成代码。如果该类实现了一个接口,你可以使用.NET DynamicProxy类。如果该类的方法是虚拟的,你可以使用Castle项目的动态代理支持。如果两者都不是这种情况,我认为生成一个facade是最简单的方法。 - Jon Skeet
@jonskeet .NET DynamicProxy类是什么?我在框架本身中找不到类似的东西。 - lysergic-acid
@liortal:我的错误,它被称为RealProxy(可怕的名字)。 - Jon Skeet
2
关于代码生成的评论。 Resharper 允许轻松实现这样的委托方法。 Alt+Ins -> 委托成员(或类似内容)。 - Snowbear
显示剩余6条评论

3
你可以了解一下PostSharp,它是一款商业产品,可以将IL注入已编译的程序集中以执行面向切面编程。你可以定义不同类型的行为,在方法执行前后发生,例如,这似乎是你想要的。由于PostSharp在后编译步骤中处理此操作,因此无需从要拦截的类创建任何继承类。
否则,如果你想要一个更 "纯粹" 的解决方案,我会按照Jon的建议创建一个包装所要拦截功能的新类。(参见装饰者模式)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接