在普通的本机库中,我可以通过简单地在导出中构建具有相同功能签名的dll来包装另一个dll并监视调用,有时甚至可以调用真正的dll。
在托管C#中,我有一个叫做“A”的dll,它是另一个应用程序的插件,它有一个派生自另一个dll中的类的类,我叫做dll“B”。我想为“B”创建一个包装器dll,因此“A”可以使用包装版本的“B”运行,甚至可能根本不使用真正版本的“B”。
B也有静态方法和其他类,我希望能够重新定义这个准包装器中的签名/声明,并使用“A”程序集来代替它。
插件dll A:
using baseDllB;
public class foopluginA : pluginclassB
{
public void methodbaz() { base.doStuff(); pluginclassB.doStaticStuff(); }
}
基本dll B:
namespace baseDllB
{
public class pluginclassB
{
public void doStuff()
{
//Do stuff
}
public static void doStaticStuff() { /*Do more stuff*/ }
}
}
插件dll
s明显参考B,所以我想要做的是重新创建B
,我可以在那里执行日志记录等。
有什么方法可以做到这一点?
你当然可以编写一个程序集,它有一个类,它将所有方法调用和内部状态转发给其他类。但是,您必须克服一些困难。
您必须使用新的包装程序集替换对原始程序集的引用。
您必须将包装器中的类更改反映到包装类中。这可能是非平凡的,特别是如果内部状态包含私有成员。如果它是一个静态类,那就容易多了。
如果您希望您的包装程序集能够加载多种包装程序集,例如选择要转发到哪个类,则需要编写一个接口并使包装的程序集派生自该接口或代码你的包装器组件会变得非常复杂。
如果您希望您的包装程序集完全是动态的,这意味着它在运行时加载了它的包装目标而只加载了您想要的那个,那么您需要大量使用反射来从包装类中获取方法和其他项。
一种可能性是RealProxy
。您可以使用the RealProxy
class提供其他类的代理实例,并且客户端代码不会知道其中的差异。 Here is a blog post with an example of its usage。