【发布时间】:2017-05-24 17:21:14
【问题描述】:
我目前正在编写一个应用程序,该应用程序当前通过 Roslyn 的工作区 API 加载项目,将指定的 C# 文件转换为语法树,然后从它创建一个内存程序集,然后最终提取 IL。
这一切正常,但是只要我在所述 C# 文件中引用任何外部库,编译就会失败,因为 Roslyn 不知道在哪里解析这些引用。
这是我目前正在做的简化版本:
元数据引用 [] 元数据引用 = { MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location), MetadataReference.CreateFromFile(typeof(DynamicAttribute).GetTypeInfo().Assembly.Location), MetadataReference.CreateFromFile(typeof(AssemblyMetadata).GetTypeInfo().Assembly.Location), }; var sourceLanguage = new CSharpLanguage(); var syntaxTree = sourceLanguage.ParseText(sourceCode, SourceCodeKind.Regular); var options = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, 优化级别:优化级别。调试, 允许不安全:真 ); CSharpCompilation 编译 = CSharpCompilation.Create("ExampleAssembly", options: options); var 流 = 新的 MemoryStream(); var 结果 = 编译。 添加引用(元数据引用) .AddSyntaxTrees(syntaxTree) .Emit(流); // 成功为假 如果(!emitResult.Success) { foreach(emitResult.Diagnostics 中的 var 诊断) { Debug.WriteLine(diagnostic.ToString()); } }Debug.WriteLine 的输出是:
我的 Roslyn 项目正在读取的文件就是这样的:
使用 MediatR; 命名空间控制台应用程序 { 公开课程序 { 公共静态无效主要(字符串[]参数) { var mediator = new Mediator(null, null); } } }我的问题是,Roslyn 是否提供 API 来自动加载文件可能具有的任何依赖项?我希望 Roslyn 工作区允许这样做,但我找不到任何东西。
【问题讨论】:
-
你确定这是由于无法加载引用,而不是例如一些语法错误?向我们展示确切的编译器错误。
-
我已经更新了我的问题以包含错误输出和我正在阅读的文件。
-
那么,您希望
using MediatR;指令能够解析您的库吗?这就是 CSharpScript 中有#r <path>的原因。甚至MetadataReferences也需要解决,参见MetadataReferenceResolver。我能想到的实现这一点的唯一方法是#1 编译,#2 检查已知错误,尝试添加引用,转到#1。但即使这样也不适用于共享命名空间的扩展方法等...... -
@m0sa 不,这不是 C# 脚本文件。我的意图是编译从项目工作区中提取的随机 C#。
-
当您说您正在“从项目”加载文件时,您是否有 .csproj 或 project.json 或其他东西可供查看?