Search code examples
c#.net-core.net-core-rc2

Compiling and running code at runtime in .NET Core 1.0


Is it possible to compile and run C# code at runtime in the new .NET Core (better .NET Standard Platform)?

I have seen some examples (.NET Framework), but they used NuGet packages that are not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0)


Solution

  • Option #1: Use the full C# compiler to compile an assembly, load it and then execute a method from it.

    This requires the following packages as dependencies in your project.json:

    "Microsoft.CodeAnalysis.CSharp": "1.3.0-beta1-20160429-01",
    "System.Runtime.Loader": "4.0.0-rc2-24027",
    

    Then you can use code like this:

    var compilation = CSharpCompilation.Create("a")
        .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
        .AddReferences(
            MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location))
        .AddSyntaxTrees(CSharpSyntaxTree.ParseText(
            @"
    using System;
    
    public static class C
    {
        public static void M()
        {
            Console.WriteLine(""Hello Roslyn."");
        }
    }"));
    
    var fileName = "a.dll";
    
    compilation.Emit(fileName);
    
    var a = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.GetFullPath(fileName));
    
    a.GetType("C").GetMethod("M").Invoke(null, null);
    

    Option #2: Use Roslyn Scripting. This will result in much simpler code, but it currently requires more setup:

    • Create NuGet.config to get packages from the Roslyn nightly feed:

        <?xml version="1.0" encoding="utf-8"?>
        <configuration>
          <packageSources>
            <add key="Roslyn Nightly" value="https://www.myget.org/F/roslyn-nightly/api/v3/index.json" />
          </packageSources>
        </configuration>
      
    • Add the following package as a dependency to project.json (notice that this is package from today. You will need different version in the future):

        "Microsoft.CodeAnalysis.CSharp.Scripting": "1.3.0-beta1-20160530-01",
      

      You also need to import dotnet (obsolete "Target Framework Moniker", which is nevertheless still used by Roslyn):

        "frameworks": {
          "netcoreapp1.0": {
            "imports": "dotnet5.6"
          }
        }
      
    • Now you can finally use Scripting:

        CSharpScript.EvaluateAsync(@"using System;Console.WriteLine(""Hello Roslyn."");").Wait();