所以我一直在寻找一种方法来做这件事,每当我找到一些东西时,都会导致一个不同的问题。
基本上,我有一个游戏机。控制台运行C#代码片段。编译的程序集需要是当前程序集的朋友,以便控制台知道当前程序集中的所有类型并可以对它们进行操作。
问题一: 每次运行控制台命令时,都会生成一个新的程序集(如果有人知道的话,我很想避免这种情况),并且要成为朋友程序集,它需要与最后一个程序集具有相同的名称。 遗憾的是,您无法卸载以前的程序集,因此新程序集无法覆盖它。这迫使我使用AppDomains。
问题二: 如果我让每个程序集使用一个单独的AppDomain,然后卸载最后一个,它可以工作,但我无法操纵当前AppDomain中的对象,因为它们不是从MarshalByRef派生的,所以当我将它们作为参数传递给它试图序列化它们的脚本。 我不喜欢AppDomains。
所以我认为最简单的方法是在同一AppDomain中生成具有不同名称的程序集,并以某种方式在运行时将它们设置为友元程序集。
我确实意识到这可能是不可能的,所以任何其他选择都是受欢迎的。
编辑: 为了更清楚。脚本需要访问主/父程序集内部。不是相反。我无法在主程序集中公开所有内容,因为我希望代码可以重用。
答案 0 :(得分:1)
如果您要生成这些程序集,为什么不公开要公开的项目public
而不是internal
?
或者,将可曝光类型标记为protected internal
并在生成的程序集中创建派生类(假设生成的程序集引用主程序集)。这将允许生成的程序集使用其派生类,并且派生类将通过受保护的成员访问主程序集。这些都不会使你的成员普遍“公开”。
您可以使用 InternalsVisibleToAttribute
,但这是在编译时。但是,听起来你是从代码片段动态编译程序集,所以你应该能够编译你想要的任何属性。
我没有意识到您希望主程序集对生成的程序集可见。正如以下问题的答案所解释的那样,您可以影响给定实例的属性,但不能静态地影响该类型。
Can attributes be added dynamically in C#?
当然,您生成的代码总是可以使用反射来获取类型。
答案 1 :(得分:0)
您可以将InternalsVisibleToAttribute添加到新程序集中。
答案 2 :(得分:0)
似乎不可能。您可以将每个程序集的成员生成为public
- 因为程序集是动态生成的,所以这不应该是一个问题
答案 3 :(得分:0)
我正在考虑一个类似于你的问题,我正在考虑某种代理程序集,它将公共方法暴露给主程序集的内部。
装配体:
就我而言,我的主程序集是一个可重用的组件,我有两种消费者。第一种是使用我的Main中的可重用组件,因此只能访问主程序集的公共成员。第二个消费者是测试第一个提到的消费者组件的测试组件。这个程序集通常想要模拟主程序集中的一些内部,因此使用代理来访问这些内部。
这可能是一种开销,特别是在生成程序集时,但它可以很好地分离问题。