3

I have a similar issue to the problem raised here Using System.Dynamic in Roslyn

When attempting to compile code with roslyn using dynamic objects I receive a compiler error:

CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.Binder.SetMember'

I have the reference to Microsoft.CSharp added. The problem only occurs when running on coreclr, it works perfectly on the full framework.

A full example is:

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

I used the technique described here http://www.strathweb.com/2016/03/roslyn-scripting-on-coreclr-net-cli-and-dnx-and-in-memory-assemblies/ to obtain the metadata references to the in memory assemblies as Assembly.Location is null for coreclr.

The project.json file:

{
  "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"
      }
    }
  }
}

I've tried this on 1.0.0-rc1-update1 and update2 and tried adding references to other assemblies but cannot figure out why it fails.

Any ideas out there?

Community
  • 1
  • 1
Steve Jackson
  • 295
  • 4
  • 9
  • I can reproduce this on dotnet CLI using recent Roslyn and without `GetMetadataReference()`, so [I reported it as a bug](https://github.com/dotnet/roslyn/issues/10693). – svick Apr 19 '16 at 19:42

0 Answers0