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. Come 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'.
Avete provato ad aggiungere un assembly redirect per quelle assemblee al vostro app.config? (E per estensione a * .exe.config) – Guvante
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
IIRC 'DesktopAssemblyIdentityComparer' ha risolto il problema una volta per me. Nota comunque che 'CSharpCompilationOptions' è immutabile ... hai provato' op = op.WithAssemblyIdentityComparer (DesktopAssemblyIdentityComparer.Default) '? – m0sa