使程序集内部在运行时对另一个程序集可见

本文关键字:程序集 另一个 运行时 内部 | 更新日期: 2023-09-27 18:36:20

所以我一直在寻找一种方法来做到这一点,每次我发现一些东西,它都会导致一个不同的问题。

基本上,我有一个游戏机。控制台运行 C# 代码片段。已编译的程序集需要是当前程序集的友元,以便控制台了解当前程序集中的所有类型并可以操作它们。

问题一:每次运行控制台命令时,都会生成一个新程序集(如果有人知道如何操作,我很想避免这种情况),并且要使其成为友元程序集,它需要与最后一个程序集具有相同的名称。遗憾的是,您无法卸载以前的程序集,因此新程序集无法覆盖它。这迫使我使用应用程序域。

问题二:如果我使每个程序集使用单独的 AppDomain,然后卸载最后一个,它可以工作,但我无法从当前 AppDomain 操作对象,因为它们不是从 MarshalByRef 派生的,所以当我将它们作为参数传递给脚本时,它会尝试序列化它们。我不喜欢应用程序域。

因此,我认为最轻松的方法是在同一 AppDomain 中生成具有不同名称的程序集,并在运行时以某种方式将它们设置为友元程序集。

我确实意识到这可能是不可能的,所以任何其他选择都是受欢迎的。

编辑:为了更清楚。脚本需要访问主/父程序集内部。反之则不然。我无法在主程序集中公开所有内容,因为我希望代码可重用。

使程序集内部在运行时对另一个程序集可见

如果要生成这些程序集,为什么不将要公开的项设为public而不是internal

或者,将可公开的类型标记为protected internal,并在生成的程序集中创建派生类(假设生成的程序集引用主程序集)。然后,这将允许生成的程序集使用其派生类,并且该派生类将通过受保护的成员访问主程序集。这些都不会使您的成员通常"公开"。

您可以使用 InternalsVisibleToAttribute ,但这是在编译时。但是,听起来您正在从代码片段动态编译程序集,因此您还应该能够在所需的任何属性中进行编译。

我没有意识到您希望主程序集对生成的程序集可见。如以下问题的回答所解释的那样,您可以影响给定实例的属性,但不能静态地针对类型。

是否可以在 C# 中动态添加属性?

当然,生成的代码始终可以使用反射来获取类型。

可以将 InternalsVisibleToAttribute 添加到新程序集。

这似乎是不可能的。您可以只生成每个程序集的成员作为public - 由于程序集是动态生成的,这应该不是问题

我正在考虑一个类似于您的问题,并且正在考虑某种将公共方法公开给主程序集内部的代理程序集。

组件:

  • 主:内部组件和内部组件对代理程序集可见;
  • 代理:用公共方式间接访问主内部;
  • 消费者:可以访问代理修改主。

就我而言,我的主程序集是一个可重用的组件,我有两种消费者。第一种只是在我的 Main 中使用可重用的组件,因此只能访问 Main 程序集的公共成员。第二个使用者是测试第一个提到的使用者程序集的测试程序集。此程序集通常希望模拟主程序集中的某些内部组件,因此使用代理访问这些内部组件。

这可能是一种开销,尤其是在生成程序集时,但它可以很好地分离关注点。