vendredi 31 mars 2017

Cannot create a compilation in Roslyn from source code

For test purposes, I need to get a System.Reflection.Assembly from a string source which contains a source code. I am using Roslyn:

SyntaxTree tree = CSharpSyntaxTree.ParseText(source);
CSharpCompilation compilation = CSharpCompilation.Create("TestCompilation", new[] { tree });

Assembly assembly = null;
using (var stream = new MemoryStream())
{
    var emitResult = compilation.Emit(stream);
    if (!emitResult.Success)
    {
        var message = emitResult.Diagnostics
            .Select(d => d.ToString())
                .Aggregate((d1, d2) => $"{d1}{Environment.NewLine}{d2}");

        throw new InvalidOperationException($"Could not emit assembly.{Environment.NewLine}{message}");
    }

    stream.Seek(0, SeekOrigin.Begin);
    assembly = Assembly.Load(stream.ToArray());
}

As you can see my attempt here is to emit a CSHarpCompilation object so that I can get the Assembly later. I am trying to do this with:

var source = @"
  namespace Root.MyNamespace1 {
    public class MyClass {
    }
  }
";

Emit errors

But I fail at var emitResult = compilation.Emit(stream) and enter the conditional which shows the error. I get 1 warning and 3 errors:

  • Warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options.
  • (3,34): Error CS0518: Predefined type 'System.Object' is not defined or imported
  • (3,34): Error CS1729: 'object' does not contain a constructor that takes 0 arguments
  • Error CS5001: Program does not contain a static 'Main' method suitable for an entry point

So it seems I need to add reference to mscorelib and it also seems like I need to tell Roslyn that I want to emit a class library, not an executable assembly. How to do that?





Aucun commentaire:

Enregistrer un commentaire