我对此处提出的问题Using System.Dynamic in Roslyn
有类似的问题当尝试使用动态对象使用roslyn编译代码时,我收到编译器错误:
CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.Binder.SetMember'
我添加了对Microsoft.CSharp的引用。问题只发生在coreclr上运行时,它完全适用于完整的框架。
一个完整的例子是:
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
public class Program
{
public static void Main(string[] args)
{
var text = @"using System.Dynamic;
public class Calculator
{
public static object Evaluate()
{
dynamic x = new ExpandoObject();
x.Result = 42;
return x.Result;
}
}";
var references = new List<MetadataReference>();
#if DNXCORE50
// reference system.runtime
references.Add(GetMetadataReference(typeof(object).GetTypeInfo().Assembly));
// reference system.dynamic.runtime
references.Add(GetMetadataReference(typeof(ExpandoObject).GetTypeInfo().Assembly));
// reference microsoft.csharp
references.Add(GetMetadataReference(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).GetTypeInfo().Assembly));
#elif DNX451
references.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
references.Add(MetadataReference.CreateFromFile(typeof(ExpandoObject).Assembly.Location));
references.Add(MetadataReference.CreateFromFile(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.Location));
#endif
var tree = SyntaxFactory.ParseSyntaxTree(text);
var compilation = CSharpCompilation.Create(
"calc.dll",
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
syntaxTrees: new[] { tree },
references: references);
using (var stream = new MemoryStream())
{
var compileResult = compilation.Emit(stream);
if (!compileResult.Success)
{
// fails here when running on coreclr
throw new Exception(compileResult.Diagnostics[0].ToString());
}
}
}
public static unsafe MetadataReference GetMetadataReference(Assembly assembly)
{
byte* b;
int length;
MetadataReference reference = null;
if (assembly.TryGetRawMetadata(out b, out length))
{
var moduleMetadata = ModuleMetadata.CreateFromMetadata((IntPtr)b, length);
var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
reference = assemblyMetadata.GetReference();
}
return reference;
}
}
我使用此处描述的技术http://www.strathweb.com/2016/03/roslyn-scripting-on-coreclr-net-cli-and-dnx-and-in-memory-assemblies/来获取对内存程序集的元数据引用,因为Assembly.Location对于coreclr是空的。
project.json文件:
{
"version": "1.0.0-*",
"description": "ConsoleApp1 Console Application",
"authors": [ "steve" ],
"tags": [ "" ],
"projectUrl": "",
"licenseUrl": "",
"compilationOptions": {
"emitEntryPoint": true,
"allowUnsafe": true
},
"dependencies": {
"Microsoft.CodeAnalysis.Common": "1.1.0-rc1-20151109-01",
"Microsoft.CodeAnalysis.CSharp": "1.1.0-rc1-20151109-01",
"System.Runtime.Loader": "4.0.0-beta-23516"
},
"commands": {
"ConsoleApp1": "ConsoleApp1"
},
"frameworks": {
"dnx451": {
"frameworkAssemblies": {
"System.Runtime": "4.0.10.0",
"System.Threading.Tasks": "4.0.0.0",
"System.Text.Encoding": "4.0.0.0",
"System.IO": "4.0.0.0",
"System.Reflection": "4.0.0.0"
}
},
"dnxcore50": {
"dependencies": {
"Microsoft.CSharp": "4.0.1-beta-23516",
"System.Collections": "4.0.11-beta-23516",
"System.Console": "4.0.0-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Threading": "4.0.11-beta-23516"
}
}
}
}
我在1.0.0-rc1-update1和update2上试过这个,并尝试添加对其他程序集的引用,但无法弄清楚它失败的原因。
有任何想法吗?