我试图编译一些针对可移植.Net库构建的代码,并且试图确定将可移植程序集加载为MetadataReference对象的正确方法。

例如,我可以像这样加载程序集,它将起作用:

var analyzerCode = "// Some analyzer code here";
var syntaxTree = CSharpSyntaxTree.ParseText(analyzerCode);

string assemblyName = System.IO.Path.GetRandomFileName();
MetadataReference[] references = new MetadataReference[]
{
    MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Runtime.dll"),
    MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Diagnostics.Debug.dll"),
    MetadataReference.CreateFromFile(typeof(System.Collections.Immutable.ImmutableArray).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Microsoft.CodeAnalysis.CSharp.CSharpCompilation).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Microsoft.CodeAnalysis.Workspace).Assembly.Location)
};

CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

using (var ms = new MemoryStream())
{
    EmitResult result = compilation.Emit(ms);
    // Check the result for errors and work with it
}


显然,这不是可移植的代码,因为我使用的文件路径只能在我的机器上工作。如果我执行以下操作:

MetadataReference.CreateFromFile(typeof(object).Assembly.Location),


我得到以下例外:


  CS0012:类型“对象”是在没有定义的程序集中定义的
  参考。您必须添加对程序集'System.Runtime的引用,
  版本= 4.0.0.0,文化=中性,PublicKeyToken = b03f5f7f11d50a3a'。


我相信这是因为运行此代码的解决方案是4.6程序集,因此typeof(object)指向4.6 System.dll。

所以我的问题是,指定可移植程序集用作Roslyn编译对象的MetadataReference实例的正确方法是什么?

最佳答案

如果您要编译的是同时引用“完整”框架4.5或4.6,并且还同时引用了可移植库,则还需要添加对外观组合件的引用以在它们之间架桥。您可以在以下位置找到它们:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades


您应该在哪里用目标版本的桌面框架替换v4.6。您应该只遍历该目录,并为在那里看到的所有程序集添加引用。

08-29 01:09