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

时间:2012-06-06 09:43:53

标签: c# runtime-compilation

所以我一直在寻找一种方法来做这件事,每当我找到一些东西时,都会导致一个不同的问题。

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

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

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

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

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

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

4 个答案:

答案 0 :(得分:1)

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

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

您可以使用InternalsVisibleToAttribute,但这是在编译时。但是,听起来你是从代码片段动态编译程序集,所以你应该能够编译你想要的任何属性。

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

Can attributes be added dynamically in C#?

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

似乎不可能。您可以将每个程序集的成员生成为public - 因为程序集是动态生成的,所以这不应该是一个问题

答案 3 :(得分:0)

我正在考虑一个类似于你的问题,我正在考虑某种代理程序集,它将公共方法暴露给主程序集的内部。

装配体:

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

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

这可能是一种开销,特别是在生成程序集时,但它可以很好地分离问题。