【问题标题】:Programmatically add methods to class?以编程方式向类添加方法?
【发布时间】:2012-11-01 01:41:23
【问题描述】:

我正在处理一个 API,它有一个包含数百万个方法的类,我知道这些方法的作用,它们只是 Web 服务的代理。

API 使用反射调用适当的方法名称在内部调用这些代理方法(不要问我为什么这样做)。

API 未实现的 Web 服务中有一些方法,我需要动态“注入”这些代理方法。

所以我的问题是:如何向现有类添加方法(不是扩展方法)?

我可以通过 Reflection.Emit 完成此操作,但我不知道 MSIL。
无论如何我要提到它,因为我已经创建了另一个类,它继承自与 API 相同的基类,并在那里实现了方法,所以也许有一种方法可以将方法复制到 API 类,因为它们只调用同一个基类的方法。

【问题讨论】:

  • 为什么需要动态“注入”它们?您真的是说人们将服务添加到您的外部 API,并且您希望能够在不重新编译的情况下调用它们吗?
  • @KirkWoll,他们提供的 .NET API 仅涵盖其 Web API 的一部分,我想添加一些方法来隐藏其他 Web 部件,但每个调用都通过调用方法的消息传递这个类通过反射,所以我想这是唯一的选择,否则我将不得不重新编写整个 API,这需要更多的努力。所以是的,我想注入这些方法。此外,我将创建一个函数来检查我的程序集(对于属性类等)并“注册所有应该注册的方法”。正如我所说,它们只是代理方法,很容易制作一个构建它们的机器人。
  • 当你在编译时知道 full API 的情况下,为什么要动态地添加方法。这对我来说毫无意义。

标签: c# .net reflection methods typedescriptor


【解决方案1】:

实际上,您不可能以您想要的方式修改现有的类。即使使用 Reflection.Emit,它也不会做你想做的事情,因为 API 调用的是特定类型,并且你不能在运行时修改类型的定义。你可以用 Reflection.Emit 做的是定义一个从代理继承的类型,但是让 API 加载你继承的类型可能会被证明是不可能的,除非他们使用依赖注入框架,这似乎不太可能。

真正做到这一点的唯一方法是使用反编译和重新编译进入并修改 dll 的字节码。这就是 Postsharp 做 AOP 的方式,但是 imo,出于任何其他原因,我永远不会这样做。

如果您可以访问此代码甚至他们的库,那么可能有更好的方法来解决您的问题。

【讨论】:

  • 让我告诉你API中的代理方法是如何调用的,API使用反射来调用X类型的方法X。所以你是说反正没有添加方法?我认为这是值得的,因为这是唯一的障碍,我查看了 API 的反编译代码。否则我将不得不重写他们已经由无数类构建的整个 API。
  • 如果你的意思是添加一个方法来输入 X,不幸的是,这在大多数(所有?)静态类型语言中是不可能的。在 Javascript 和 Ruby 等动态类型语言中也称为猴子补丁。
  • 好的。我想我找到了一种方法,我将继承该代理类,并且我有一种方法可以告诉 API 使用我的代理类,我现在正在检查它。无论如何感谢您的输入!
  • 太棒了!我很惊讶 API 如此灵活,因为它的设计如此奇怪,但很高兴听到。
  • :( Nops...这是基本方法中的一条静态行,告诉 API 使用代理类 X。我希望我可以误导 API 使用继承 API 代理类的代理类。它正在更改单个 typeof(X)...
【解决方案2】:

在我看来,您也将使用反射,省去一些麻烦,并将该逻辑包装在扩展方法中(即使您明确表示不这样做)。

如果您有更多信息说明为什么在这种情况下扩展方法不是一个好主意,或者您为什么想做一些 API 开发人员没有公开的事情,我也许可以想出一些更有用的东西。

【讨论】:

  • 这正是扩展方法的设计目的。 +1
  • 没有。 API 是决定调用什么方法的人,这个决定是由调用名称(字符串)做出的,所以我看到的唯一选择是添加我的问题中描述的方法,扩展方法不起作用。
  • 否定,API 让您可以访问开发人员认为您应该能够访问的功能。其他任何东西都不是 API。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 2013-06-17
  • 1970-01-01
相关资源
最近更新 更多