And*_*ell 20 c# compilation assembly.load
假设我有两个C#应用程序 - game.exe(XNA,需要支持Xbox 360)和editor.exe(在WinForms中托管的XNA) - 它们共享一个engine.dll可以完成绝大部分工作的程序集.
现在让我们说我想添加一些基于C#的脚本(它不是"脚本",但我会称之为).每个级别都有自己继承自基类的类(我们称之为LevelController).
这些是这些脚本的重要约束:
它们需要是真实的,编译好的C#代码
他们应该需要最少的手动"粘合"工作,如果有的话
它们必须与其他所有内容在同一个AppDomain中运行
对于游戏 - 这非常简单:所有脚本类都可以编译成一个程序集(比如说levels.dll),并且可以根据需要使用反射来实例化各个类.
编辑要困难得多.编辑器能够在编辑器窗口中"玩游戏",然后将所有内容重置回原来的位置(这就是编辑器首先需要了解这些脚本的原因).
我想要实现的基本上是编辑器中的"重新加载脚本"按钮,它将重新编译并加载与正在编辑的级别相关联的脚本类,当用户按下"播放"按钮时,创建最近的实例编译脚本.
其结果将是编辑器中的快速编辑测试工作流程(而不是替代方案 - 保存级别,关闭编辑器,重新编译解决方案,启动编辑器,加载级别,测试).
现在我想我已经找到了实现这个目标的潜在方法 - 这本身就会产生一些问题(如下所示):
.cs将给定级别(或者,如果需要,整个levels.dll项目)所需的文件集合编译为临时的,唯一命名的程序集.那个集会需要参考engine.dll.如何在运行时以这种方式调用编译器?如何让它输出这样的程序集(我可以在内存中执行)吗?
加载新装配.我在同一个进程中加载具有相同名称的类是否重要?(我的印象是名称是由程序集名称限定的?)
现在,正如我所提到的,我无法使用AppDomains.但是,另一方面,我不介意泄漏旧版本的脚本类,因此卸载的能力并不重要.除非是吗?我假设加载可能几百个组件是可行的.
在播放关卡时,实例是从刚加载的特定程序集继承自LevelController的类.这该怎么做?
最后:
这是一种明智的做法吗?它可以做得更好吗?
更新:这些天我使用一种更简单的方法来解决潜在的问题.
查看 Microsoft.CSharp.CSharpCodeProvider 和 System.CodeDom.Compiler 周围的命名空间。
编译 .cs 文件集合
应该非常简单,例如http://support.microsoft.com/kb/304655
我将同名的类加载到同一个进程中会重要吗?
一点也不。这只是名字。
实例化从 LevelController 继承的类。
加载您创建的程序集,例如 Assembly.Load 等。使用反射查询要实例化的类型。获取构造函数并调用它。
| 归档时间: |
|
| 查看次数: |
6341 次 |
| 最近记录: |