Microsoft.scodeanalysis:使用Newtonsoft Jobignt编译动态代码的错误



我有一个无法解决的奇怪问题。我在大多数情况下都成功地编译了动态组件,但提出了一个奇怪的问题,汇编了以下行:

返回new jobject()。properties()。elementat(0).value();

有错误:

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?) '

当在项目中创建为真实类时,发射的文本输出正常工作,而在动态组件中则不能。该项目是ASP.NET Core 2.2项目,它引用了一个创建动态组件的程序集。

这是创建汇编的代码:

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

(显示的代码不是用于工作目的,简单地证明了问题)

预先感谢

解决方案是添加特定的参考:

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

相关内容

  • 没有找到相关文章

最新更新