Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在.NET中包装程序集?_C#_Wrapper - Fatal编程技术网

C# 如何在.NET中包装程序集?

C# 如何在.NET中包装程序集?,c#,wrapper,C#,Wrapper,在普通的本机库中,我可以包装另一个dll并监视调用,只需在导出中使用相同的函数签名构建一个dll,有时甚至可以调用真实的dll 在托管C#中,我有一个名为“a”的dll,它是另一个应用程序的插件,该应用程序的类派生自另一个dll(我称为dll“B”)中的类。我想为“B”创建一个包装dll,这样“a”就可以与“B”的包装版本一起工作,甚至可能根本不用“B”的真实版本 B还有静态方法和其他类,我希望能够在这个准包装器中重新定义签名/声明,并让“A”程序集使用它 插件dll A: using base

在普通的本机库中,我可以包装另一个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
。您可以使用来提供其他类的代理实例,而客户端代码不会知道其中的区别

程序到接口而不是实现。。。我无法访问基类的源代码。我之所以不在我的测试平台内编译源代码,是因为必须剪切代码并重新编译的部署问题,而且我需要将资源嵌入插件而不是测试平台。我在这里留下了几个选项——在我的上一个选项中,我提到了反射。使用它,您可以获取任何类或值类型的每个成员(公共或私有、方法、属性或字段)的信息。反射是必需的,现在的问题是在dll中获取从包装类继承的继承类。但你知道我刚才试过什么吗?重新实现每个成员、静态类等,以创建我自己的“B”类副本,它就可以工作了。它使用的副本没有任何错误,但我是否应该知道使用这种方法的过程中有任何问题?不应该有任何问题。如果你想要一个完美的替代品,你可以设计一个接口,但是如果你不介意用你的方式修改少量的代码,那就好了。如果接口被用于插件模型,我永远不会问,但是插件依赖于一个继承的类和位于“B”dll中其他各种类中的几个静态方法。因为我不是设计插件模型的人,所以我同意简化模型是很简单的。这实际上看起来是可行的。在动态加载程序集时,如何让目标类从代理继承?同样,如果这不起作用。我在另一篇评论(神秘地消失了)中听说,我可以设置一个禁用验证的功能,我可以做什么让插件加载一个简单的“B”库构建,只需使用相同的确切成员和类名重新实现原始的“B”?假设我构建了一个具有相同确切类的库,定义所有精确的方法等。动态加载插件后,我是否可以将其继承的依赖项指向副本?假设我一开始就能做到:嗯,我不知道你会怎么做。如果您对应用程序和DLL完全没有控制权,那么这可能会很困难。。。RealProxy只在从MarshallByRefObject派生的接口或类型上工作,所以如果您不能更改它,那么您将在使用它时遇到问题。嗯,糟糕。甚至不能继续使用RealProxy,这比使用基类要少得多。