我有一个无法解决的奇怪问题。我在大多数情况下都成功地编译了动态组件,但提出了一个奇怪的问题,汇编了以下行:
返回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")),