简体   繁体   English

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

[英]How to get roslyn to compile when referenced assemblies have references to both mscorlib 2.0.5.0 and 4.0.0.0

I'm dynamically building a class that uses Microsoft.OData.Client this library have references to both mscorlib 2.0.5.0 (i guess the PCL) and 4.0.0.0. 我正在动态构建一个使用Microsoft.OData.Client的类,这个库引用了mscorlib 2.0.5.0(我猜PCL)和4.0.0.0。 在此输入图像描述

I want to compile my class with roslyn, as part of a larger program, but I can't seem to get it to work. 我想用roslyn编译我的类,作为一个更大的程序的一部分,但我似乎无法让它工作。 My Roslyn compiler code is pretty minimalistic 我的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());                 
                }
        }

These are the errors I get 这些是我得到的错误

CS0012: The type 'Object' is defined in an assembly that is not referenced. CS0012:类型“对象”在未引用的程序集中定义。 You must add a reference to assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'. 您必须添加对程序集'mscorlib,Version = 2.0.5.0,Culture = neutral,PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'的引用。

CS0012: The type 'XmlReader' is defined in an assembly that is not referenced. CS0012:类型'XmlReader'在未引用的程序集中定义。 You must add a reference to assembly 'System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'. 您必须添加对程序集'System.Xml,Version = 2.0.5.0,Culture = neutral,PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'的引用。

As you predicted in the comments DesktopAssemblyIdentityComparer is the solution. 正如您在评论中预测的那样, DesktopAssemblyIdentityComparer就是解决方案。 However, CSharpCompilationOptions is immutable, and the WithAssemblyIdentityComparer method returns a new instance, so you have to use it like this: 但是, 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM