2016-02-29 20 views
5

Microsoft.OData.Clientを使用するクラスを動的に構築しています。このライブラリはmscorlib 2.0.5.0(i PCLを推測する)と4.0.0.0。 enter image description hereリファレンスアセンブリがmscorlib 2.0.5.0と4.0.0.0の両方への参照を持つときにroslynをコンパイルする方法

大きなプログラムの一環として、私のクラスをroslynでコンパイルしたいのですが、動作させることができません。型 'オブジェクトの参照されていないアセンブリで定義されています。私のロザリンコンパイラコードは、これらは私が

CS0012は、取得エラーです

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());     
       } 
     } 

かなり最小限です。アセンブリ 'mscorlib、Version = 2.0.5.0、Culture = neutral、PublicKeyToken = 7cec85d7bea7798e、Retargetable = Yes'への参照を追加する必要があります。

CS0012: 'XmlReader'型は、参照されていないアセンブリで定義されています。アセンブリ 'System.Xml、Version = 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

答えて

4

コメントで予測したとおり、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); 
関連する問題