我将基于Roslyn的脚本引擎嵌入到我的应用程序中,并开始面临一些问题.将引用加载到我的引擎时,我会执行以下操作
var engine = new Roslyn.Scripting.CSharp.ScriptEngine();
engine.AddReference("MyAssemblyLocation");
Run Code Online (Sandbox Code Playgroud)
问题:
MyAssemblyLocation程序集引用其他程序集,我如何告诉Roslyn在不执行任何程序集的情况下加载它们engine.AddReference("MyAssemblyLocation");MyAssemblyLocation谢谢.
小智 6
1)简短回答:您需要在将要在脚本中使用其类型的所有程序集上添加AddReference.
详细信息:C#编译器不会猜测依赖文件的位置.程序集文件未指定其所有依赖项的完整路径.它只包含它们的名称,并且通常不足以使编译器能够找到程序集文件.
更多细节:有两种依赖关系.我将它们称为编译时依赖项(a)和运行时依赖项(b).
(a)假设你在程序集B.dll中有"公共类A:B {}",程序集B.dll中有"公共类B {}",而你的脚本正在使用A,比如说你创建了一个新实例:"new一个()".在这种情况下,编译器要求您添加对A.dll和B.dll的引用,因为A派生自B,编译器需要分析您使用的每种类型的继承层次结构.所以B.dll是脚本的编译时依赖 - 编译器需要它才能正确分析你的脚本.
(b)考虑另一个例子:"A.dll中的公共类A {公共对象M(){return new B();}}"和上面的相同B.dll.现在编译"new A().M()"时,编译器不需要知道B,因为对B的引用仅发生在方法M的主体中,并且编译器不分析导入方法的主体.在这种情况下,只需添加对A.dll的引用即可编译脚本.当脚本执行时,它调用方法M.此时CLR加载程序集B.这有点复杂,所以我将跳过详细信息,但在常见情况下,我们将能够为您找到程序集,所以你不要需要明确添加引用.
2)我建议使用带有Assembly对象的AddReference重载.类似于:engine.AddReference(typeof(SomeTypeInAssemblyFoo).Assembly)加载包含类型SomeTypeInAssemblyFoo的程序集Foo.
3)不是一个简单的.您可以使用Reflection或Roslyn API枚举所有引用并加载其中的每个引用.
如果解释不清楚或您想了解更多细节,请随时提出进一步的问题.