如何让引用的程序集引用程序集时引用roslyn编译mscorlib 2.0.5.0和4.0.0.0

问题描述:

我在动态构建一个使用Microsoft.OData.Client的类此库引用了mscorlib 2.0.5.0(i猜测PCL)和4.0.0.0。 enter image description here如何让引用的程序集引用程序集时引用roslyn编译mscorlib 2.0.5.0和4.0.0.0

我想用roslyn编译我的类,作为一个更大的程序的一部分,但我似乎无法让它工作。我的罗斯林编译代码是非常简约的

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(s); 
      string assemblyName = Path.GetRandomFileName(); 

      List<MetadataReference> references = new List<MetadataReference>() 
      { 
       MetadataReference.CreateFromFile(typeof(DataServiceActionQuery).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(ODataAction).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(GeneratedCodeAttribute).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(IEdmModel).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(TimeOfDay).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(object).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(XmlDocument).Assembly.Location), 
       // MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile328\mscorlib.dll") 

      }; 

      references.AddRange(Directory.GetFiles(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades").Select(f => MetadataReference.CreateFromFile(f))); 

      var op = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); 
      //op.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default); 
      //CSharpCompilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default); 
      CSharpCompilation compilation = CSharpCompilation.Create(
       assemblyName, 
       syntaxTrees: new[] { syntaxTree }, 
       references: references, 
       options: op); 
      Assembly assembly = null; 
      using (var ms = new MemoryStream()) 
      { 
       EmitResult result = compilation.Emit(ms); 

       if (!result.Success) 
       { 
        IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic => 
         //diagnostic.IsWarningAsError || 
         diagnostic.Severity == DiagnosticSeverity.Error); 

        foreach (Diagnostic diagnostic in failures) 
        { 
         Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage()); 
        } 
       } 
       else 
       { 
        ms.Seek(0, SeekOrigin.Begin); 
        assembly = Assembly.Load(ms.ToArray());     
       } 
     } 

这些都是错误的,我得到

CS0012:类型“对象”在未引用的程序集定义。您必须添加对程序集'mscorlib的引用,Version = 2.0.5.0,Culture = neutral,PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'。

CS0012:类型'XmlReader'是在未引用的程序集中定义的。您必须添加对程序集'System.Xml的引用,版本= 2.0.5.0,Culture = neutral,PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'。

+0

您是否尝试过加入装配重定向这些组件到你的app.config? (并扩展到* .exe.config) – Guvante

+0

我无法获得程序集重定向来做任何事情 - 也不认为这是这里的问题。问题很可能是我如何设置roslyn编译器。 – sjkp

+0

IIRC'DesktopAssemblyIdentityComparer'为我解决了这个问题一次。但是请注意,'CSharpCompilationOptions'也是不可变的......你有没有试过'op = op.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)'? – m0sa

正如您在评论中预测的DesktopAssemblyIdentityComparer是解决方案。然而,CSharpCompilationOptions是不可改变的,而WithAssemblyIdentityComparer方法返回一个新的实例,所以你必须使用这样的:

var op = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); 
op = op.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default); 
CSharpCompilation compilation = CSharpCompilation.Create(
    assemblyName, 
    syntaxTrees: new[] { syntaxTree }, 
    references: references, 
    options: op);