使程序集内部在运行时对另一个程序集可见
本文关键字:程序集 另一个 运行时 内部 | 更新日期: 2023-09-27 18:36:20
所以我一直在寻找一种方法来做到这一点,每次我发现一些东西,它都会导致一个不同的问题。
基本上,我有一个游戏机。控制台运行 C# 代码片段。已编译的程序集需要是当前程序集的友元,以便控制台了解当前程序集中的所有类型并可以操作它们。
问题一:每次运行控制台命令时,都会生成一个新程序集(如果有人知道如何操作,我很想避免这种情况),并且要使其成为友元程序集,它需要与最后一个程序集具有相同的名称。遗憾的是,您无法卸载以前的程序集,因此新程序集无法覆盖它。这迫使我使用应用程序域。
问题二:如果我使每个程序集使用单独的 AppDomain,然后卸载最后一个,它可以工作,但我无法从当前 AppDomain 操作对象,因为它们不是从 MarshalByRef 派生的,所以当我将它们作为参数传递给脚本时,它会尝试序列化它们。我不喜欢应用程序域。
因此,我认为最轻松的方法是在同一 AppDomain 中生成具有不同名称的程序集,并在运行时以某种方式将它们设置为友元程序集。
我确实意识到这可能是不可能的,所以任何其他选择都是受欢迎的。
编辑:为了更清楚。脚本需要访问主/父程序集内部。反之则不然。我无法在主程序集中公开所有内容,因为我希望代码可重用。
如果要生成这些程序集,为什么不将要公开的项设为public
而不是internal
?
或者,将可公开的类型标记为protected internal
,并在生成的程序集中创建派生类(假设生成的程序集引用主程序集)。然后,这将允许生成的程序集使用其派生类,并且该派生类将通过受保护的成员访问主程序集。这些都不会使您的成员通常"公开"。
您可以使用
InternalsVisibleToAttribute
,但这是在编译时。但是,听起来您正在从代码片段动态编译程序集,因此您还应该能够在所需的任何属性中进行编译。
我没有意识到您希望主程序集对生成的程序集可见。如以下问题的回答所解释的那样,您可以影响给定实例的属性,但不能静态地针对类型。
是否可以在 C# 中动态添加属性?
当然,生成的代码始终可以使用反射来获取类型。
可以将 InternalsVisibleToAttribute 添加到新程序集。
这似乎是不可能的。您可以只生成每个程序集的成员作为public
- 由于程序集是动态生成的,这应该不是问题
我正在考虑一个类似于您的问题,并且正在考虑某种将公共方法公开给主程序集内部的代理程序集。
组件:
- 主:内部组件和内部组件对代理程序集可见;
- 代理:用公共方式间接访问主内部;
- 消费者:可以访问代理修改主。
就我而言,我的主程序集是一个可重用的组件,我有两种消费者。第一种只是在我的 Main 中使用可重用的组件,因此只能访问 Main 程序集的公共成员。第二个使用者是测试第一个提到的使用者程序集的测试程序集。此程序集通常希望模拟主程序集中的某些内部组件,因此使用代理访问这些内部组件。
这可能是一种开销,尤其是在生成程序集时,但它可以很好地分离关注点。