我遇到一个无法解决的奇怪问题。我在大多数情况下已经成功地编译了动态程序集,但是在编译以下行时遇到了一个奇怪的问题:
返回新的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();
}
}
(显示的代码并非旨在用于工作目的,因此已简化为演示问题)
预先感谢
答案 0 :(得分:1)
解决方案是添加特定的引用:
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Linq.Expressions.dll")),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Linq.dll")),