15

I'm trying to port some .net code to the new Core runtime and I'm having a bad time porting some on-the-fly compilation.

To resume, it always asks me for a reference to System.Runtime and mscorlib, but have no clue on how to reference them.

As a side note, I can't reference Framework 4.6 as the project must be published to a Linux machine with .net Core.

This is the minimum code:

        string testClass = @"using System; 
        namespace test{

         public class tes
         {

           public string unescape(string Text)
          { 
            return Uri.UnescapeDataString(Text);
          } 

         }

        }";

        var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll")
            .WithOptions(new CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary))
            .AddReferences(
            MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location),
            MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location)
            )
            .AddSyntaxTrees(CSharpSyntaxTree.ParseText(testClass));

        var eResult = compilation.Emit("test.dll");

It always complains about the need of mscorlib (in this example) and System.Runtime (in my real project).

I'm using the Microsoft.CodeAnalysis.CSharp package version 2.0.0-beta3

Any ideas on how to compile on the fly with Roslyn and .net Core?

Gusman
  • 14,905
  • 2
  • 34
  • 50

1 Answers1

19

Ok, got it finally working:

    string testClass = @"using System; 
    namespace test{

     public class tes
     {

       public string unescape(string Text)
      { 
        return Uri.UnescapeDataString(Text);
      } 

     }

    }";

    var dd = typeof(Enumerable).GetTypeInfo().Assembly.Location;
    var coreDir = Directory.GetParent(dd);

    var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll")
        .WithOptions(new CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary))
        .AddReferences(
        MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location),
        MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location),
        MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"),
        MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Runtime.dll")
        )
        .AddSyntaxTrees(CSharpSyntaxTree.ParseText(testClass));

    var eResult = compilation.Emit("test.dll");

I don't like it because the hardcoding, but it seems it's the only way to get it work.

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
Gusman
  • 14,905
  • 2
  • 34
  • 50
  • 1
    A more elegant way to get the runtime directory is to use `System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();` instead of getting the assembly location of an arbitrary type. – nullPainter Aug 23 '19 at 23:59
  • 2
    @nullPainter I tried it but had problems, if I recall it right if the program is published as standalone it failed to find the libraries. – Gusman Sep 04 '19 at 10:44
  • Did you try using MetadataReference.CreateFromFile(typeof(object).Assembly.Location) (with a lowercase 'o')? – Patrice Cote Nov 15 '19 at 14:46