【问题标题】:How to wrap assemblies in .NET?如何在.NET 中包装程序集?
【发布时间】:2011-08-03 21:32:54
【问题描述】:

在普通的原生库中,我可以包装另一个 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*/ }
   }
}

dlls 插件显然引用了 B,所以我想做的是重新创建 B,我可以在其中执行日志记录等。

有什么方法可以做到这一点?

【问题讨论】:

标签: c# wrapper


【解决方案1】:

您当然可以编写一个程序集,该程序集有一个将其所有方法调用和内部状态转发给其他类的类。但是,您必须克服一些困难。

您必须用新的包装程序集替换对原始程序集的引用。

您必须将包装器中的类更改反映到被包装的类。这可能很重要,尤其是在内部状态包含私有成员的情况下。如果是静态类,那就简单多了。

如果您希望您的包装程序集能够加载多种包装程序集,例如选择要转发到哪个类,您需要编写一个接口并使包装程序集从该接口派生,否则包装程序集中的代码会变得非常复杂。

如果您希望您的包装程序集是完全动态的,这意味着它在运行时加载其包装的目标并且只加载您想要的目标,您需要大量使用反射来从包装的类中获取方法和其他项目。

【讨论】:

  • 我无权访问基类的源代码。我没有在我的测试台中编译源代码的原因是因为部署问题必须删除代码并重新编译,而且我需要将资源嵌入到插件而不是测试台中。跨度>
  • 我在这里留下了几个选项——在我的最后一个选项中,我提到了反射。使用它,您可以获得任何类或值类型的每个成员、公共或私有、方法或属性或字段的信息。
  • 反射是强制性的,现在的问题是让一个 dll 中的继承类从一个包装类继承。但你知道我刚刚尝试了什么吗?重新实现每个成员、静态类等,以创建我自己的“B”类副本,并且它可以工作。它使用副本没有任何错误,但我应该注意使用这种方法的任何问题吗?
  • 应该没有任何问题。如果您想要完美的替换,您可以设计一个接口,但如果您不介意按照您的方式更改少量代码,那也没关系。
  • 有接口用于插件模型我永远不会问,但插件依赖于一个继承的类和位于“B”dll中各种其他类中的几个静态方法。由于我不是设计插件模型的人,我同意简化模型是微不足道的。
【解决方案2】:

一种可能性是RealProxy。您可以使用the RealProxy class 提供其他类的代理实例,客户端代码不会知道其中的区别。 Here is a blog post with an example of its usage.

【讨论】:

  • 这实际上看起来足够可行。我正在动态加载程序集,如何让目标类从代理继承?
  • 另外,如果这不起作用。我在另一条评论中听到(神秘地消失了),我可以设置一些东西来禁用验证,我能做些什么来让插件加载一个简单的“B”库构建,它只是用完全相同的成员名和类名?
  • 假设我已经建立了一个具有相同确切类的库,定义了所有确切的方法等。在动态加载插件之后,我是否可以将其继承的依赖项指向副本?假设我首先可以做到这一点:s
  • 嗯,我不知道你会怎么做。如果您完全无法控制应用程序和 DLL,那么这可能会很困难...... RealProxy 仅适用于从 MarshalByRefObject 派生的接口或类型,因此如果您无法更改它,那么您将在使用它时遇到问题。跨度>
  • 嗯,无赖。甚至无法继续使用 RealProxy 比使用基类少得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
相关资源
最近更新 更多