简体   繁体   English

Microsoft.CodeAnalysis:使用Newtonsoft JObject编译动态代码时出错

[英]Microsoft.CodeAnalysis: Error compiling dynamic code with Newtonsoft JObject

I'm having a strange problem that I can't fix. 我遇到一个无法解决的奇怪问题。 I have been compiling dynamic assemblies successfully for the most part but have come up with a strange problem compiling the following line: 我在大多数情况下一直成功地编译了动态程序集,但是在编译以下行时遇到了一个奇怪的问题:

return new JObject().Properties().ElementAt(0).Value(); 返回新的JObject()。Properties()。ElementAt(0).Value();

with the error: 与错误:

System.ApplicationException: 'Error creating dynamic code assembly 'IEnumerable<JProperty>' does not contain a definition for 'ElementAt' and no accessible extension method 'ElementAt' accepting a first argument of type 'IEnumerable<JProperty>' could be found (are you missing a using directive or an assembly reference?) '

The emitted text output works fine when created as a real class in the project but not when in a dynamic assembly. 当在项目中创建为真实类时,发出的文本输出工作正常,但在动态装配中创建时,则无法正常工作。 The project is an asp.net core 2.2 project and it references an assembly which creates the dynamic assemblies. 该项目是一个asp.net core 2.2项目,它引用了一个创建动态程序集的程序集。

Here is the code that creates the assembly: 这是创建程序集的代码:

public static class Class2
{
    public static Assembly GenerateAssenbly()
    {

        //generate the code
        StringBuilder sb = new StringBuilder("");
        sb.AppendLine("using System;");
        sb.AppendLine("using System.Linq;");

        sb.AppendLine("using Newtonsoft.Json;");
        sb.AppendLine("using Newtonsoft.Json.Linq;");

        sb.AppendLine("namespace test");
        sb.AppendLine("{");
        sb.AppendLine($"class Parser");
        sb.AppendLine("{");

        sb.AppendLine($"public object test() ");
        sb.AppendLine("{");
        sb.AppendLine("return new JObject().Properties().ElementAt(0).Value<string>();");
        sb.AppendLine("}");

        sb.AppendLine("}"); //class
        sb.AppendLine("}"); //namespace

        SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sb.ToString());

        var runtimeAssemblyDirectory = Path.GetDirectoryName(typeof(object).Assembly.Location);
        string assemblyName = Path.GetRandomFileName();
        MetadataReference[] references = new MetadataReference[]
        {
            MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
            MetadataReference.CreateFromFile(Assembly.GetExecutingAssembly().Location),
            MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Runtime.dll")),
            MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "mscorlib.dll")),
            MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.dll")),
            MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "netstandard.dll")),
            MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Core.dll")),

            MetadataReference.CreateFromFile(typeof(JObject).GetTypeInfo().Assembly.Location),
        };

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


        Debug.Print(sb.ToString()); // copy output to a class to test

        using (var ms = new MemoryStream())
        {
            EmitResult result = compilation.Emit(ms);

            if (!result.Success)
            {
                throw new ApplicationException($"Error creating dynamic code assembly " + GetCompilerResultsErrors(result));
            }
            else
            {
                return Assembly.Load(ms.GetBuffer());
            }
        }
    }

    private static string GetCompilerResultsErrors(EmitResult result)
    {
        StringBuilder sb = new StringBuilder();

        IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
            diagnostic.IsWarningAsError ||
            diagnostic.Severity == DiagnosticSeverity.Error);

        foreach (Diagnostic diagnostic in failures)
        {
            sb.AppendLine(diagnostic.GetMessage());
        }

        return sb.ToString();
    }
}

(the code shown is not intended for working purposes, it is simplified to demonstrate the problem) (显示的代码并非用于工作目的,它被简化以演示问题)

Thanks in advance, 提前致谢,

solution was to add specific references: 解决方案是添加特定的参考:

MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Linq.Expressions.dll")),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Linq.dll")),

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

相关问题 无法加载文件或程序集 Microsoft.CodeAnalysis - Could not load file or assembly Microsoft.CodeAnalysis 在Roslyn与Microsoft.CodeAnalysis中添加MetadataReference - Adding MetadataReference in Roslyn Vs Microsoft.CodeAnalysis Microsoft.CodeAnalysis无法加载文件 - Microsoft.CodeAnalysis failed to load file 在哪里阅读Microsoft.CodeAnalysis的文档? - Where to read docs for Microsoft.CodeAnalysis? 为什么 Microsoft 分析器找不到 Microsoft.CodeAnalysis? - Why can't Microsoft analyzers find Microsoft.CodeAnalysis? 使用Roslyn(Microsoft.CodeAnalysis)查询WebSite项目的信息 - Using Roslyn (Microsoft.CodeAnalysis) to query information of WebSite projects 合并 SonarAnalyzer.CSharp 和 Microsoft.CodeAnalysis 规则集 - Merge SonarAnalyzer.CSharp and the Microsoft.CodeAnalysis rulesets 如何在 memory 中编译并使用 Microsoft.CodeAnalysis 获取程序集 - How to compile in memory and get assembly using Microsoft.CodeAnalysis SonarQube 没有找到 Microsoft.CodeAnalysis 1.3.1.0 但已安装 - SonarQube doesnt find Microsoft.CodeAnalysis 1.3.1.0 but it is installed Microsoft.CodeAnalysis.FxCopAnalyzers 和 Microsoft.CodeAnalysis 之间有什么区别? - What's the difference between Microsoft.CodeAnalysis.FxCopAnalyzers and Microsoft.CodeAnalysis?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM