2016-02-29 16 views
5

Sto costruendo dinamicamente una classe che usa Microsoft.OData.Client questa libreria ha riferimenti a entrambi mscorlib 2.0.5.0 (i indovina il PCL) e 4.0.0.0. enter image description hereCome compilare roslyn quando gli assembly referenziati hanno riferimenti a mscorlib 2.0.5.0 e 4.0.0.0

Voglio compilare la mia classe con roslyn, come parte di un programma più ampio, ma non riesco a farlo funzionare. Il mio codice compilatore Roslyn è piuttosto minimalista

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

Questi sono gli errori ottengo

CS0012: Il tipo 'Oggetto' è definito in un assembly che non viene fatto riferimento. È necessario aggiungere un riferimento all'assembly 'mscorlib, Version = 2.0.5.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e, Retargetable = Yes'.

CS0012: il tipo 'XmlReader' è definito in un assieme a cui non viene fatto riferimento. È necessario aggiungere un riferimento all'assembly 'System.Xml, Version = 2.0.5.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e, Retargetable = Yes'.

+0

Avete provato ad aggiungere un assembly redirect per quelle assemblee al vostro app.config? (E per estensione a * .exe.config) – Guvante

+0

Non riesco a ottenere il reindirizzamento di assembly per fare qualsiasi cosa - anche non penso che questo sia il problema qui. Il problema è molto probabilmente il modo in cui ho configurato il compilatore di Roslyn. – sjkp

+0

IIRC 'DesktopAssemblyIdentityComparer' ha risolto il problema una volta per me. Nota comunque che 'CSharpCompilationOptions' è immutabile ... hai provato' op = op.WithAssemblyIdentityComparer (DesktopAssemblyIdentityComparer.Default) '? – m0sa

risposta

4

Come previsto nei commenti DesktopAssemblyIdentityComparer è la soluzione. Tuttavia, CSharpCompilationOptions è immutabile, e il metodo WithAssemblyIdentityComparer restituisce una nuova istanza, quindi bisogna usare in questo modo:

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