我当前正在编写一个应用程序,该应用程序当前通过Roslyn的工作区API加载项目,将指定的C#文件转换为语法树,然后从中创建内存中程序集,然后最终提取IL。
一切都很好,但是一旦我引用了上述C#文件中的任何外部库,编译就会失败,因为Roslyn不知道在哪里解析这些引用。
这是我目前正在做的简化版本:
MetadataReference [] metaDatareferences = {
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语法Tree = sourceLanguage.ParseText(sourceCode,SourceCodeKind.Regular);
var options = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
OptimizationLevel:OptimizationLevel.Debug,
allowUnsafe:正确
);
CSharpCompilation编译= CSharpCompilation.Create(“ ExampleAssembly”,options:options);
var stream = new MemoryStream();
var结果=编译。
AddReferences(metaDatareferences)
.AddSyntaxTrees(syntaxTree)
.Emit(stream);
//成功是错误的
如果(!emitResult.Success)
{
foreach(emitResult.Diagnostics中的var诊断)
{
Debug.WriteLine(diagnostic.ToString());
}
}Debug.WriteLine
的输出为:
(1,7):错误CS0246:找不到类型或名称空间名称'MediatR'(您是否缺少using指令或程序集引用?)
(9,32):错误CS0246:找不到类型或名称空间名称“ Mediator”(您是否缺少using指令或程序集引用?)
我的Roslyn项目正在读取的文件就是这样:
使用MediatR;
命名空间ConsoleApplication
{
公共课程
{
公共静态无效的Main(string [] args)
{
var mediator = new Mediator(null,null);
}
}
}
我的问题是,罗斯林是否提供API以自动加载文件可能具有的任何依赖关系?我希望罗斯林(Roslyn)工作区能够完成此操作,但是我什么都没找到。
最佳答案
如果MediatR控制台项目是project.json
项目,则可以使用ProjectJsonWorkspace
中的"Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-1-003177"
。您可以将其指向您的project.json
并获得一个Compilation
对象,这将为您完成获取项目引用,文件引用等的所有艰苦工作。然后您可以从此处发出IL。
这是一个例子:
var compilation = new ProjectJsonWorkspace(@"PathToYour\project.json").CurrentSolution.Projects.First().GetCompilationAsync().Result;
var stream = new MemoryStream();
var emitResult = compilation.Emit(stream);
或者,如果您需要完全控制,则可以继续使用
CSharpCompilation.Create
,从此处的compilation
对象复制所需内容,然后传入SyntaxTree
。希望能有所帮助。