How to Compile and Execute New Code at Runtime in .Net

Is it possible to compile and execute new code at runtime in .NET?

Yes! Using methods found in the Microsoft.CSharp, System.CodeDom.Compiler, and System.Reflection name spaces. Here is a simple console app that compiles a class ("SomeClass") with one method ("Add42") and then allows you to invoke that method. This is a bare-bones example that I formatted down to prevent scroll bars from appearing in the code display. It is just to demonstrate compiling and using new code at run time.

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;

namespace RuntimeCompilationTest {
class Program
{
static void Main(string[] args) {
string sourceCode = @"
public class SomeClass {
public int Add42 (int parameter) {
return parameter += 42;
}
}";
var compParms = new CompilerParameters{
GenerateExecutable = false,
GenerateInMemory = true
};
var csProvider = new CSharpCodeProvider();
CompilerResults compilerResults =
csProvider.CompileAssemblyFromSource(compParms, sourceCode);
object typeInstance =
compilerResults.CompiledAssembly.CreateInstance("SomeClass");
MethodInfo mi = typeInstance.GetType().GetMethod("Add42");
int methodOutput =
(int)mi.Invoke(typeInstance, new object[] { 1 });
Console.WriteLine(methodOutput);
Console.ReadLine();
}
}
}

Compiling and running code at runtime in .NET Core 1.0

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();

Is it possible to dynamically compile and execute C# code fragments?

The best solution in C#/all static .NET languages is to use the CodeDOM for such things. (As a note, its other main purpose is for dynamically constructing bits of code, or even whole classes.)

Here's a nice short example take from LukeH's blog, which uses some LINQ too just for fun.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

class Program
{
static void Main(string[] args)
{
var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "foo.exe", true);
parameters.GenerateExecutable = true;
CompilerResults results = csc.CompileAssemblyFromSource(parameters,
@"using System.Linq;
class Program {
public static void Main(string[] args) {
var q = from i in Enumerable.Range(1,100)
where i % 2 == 0
select i;
}
}");
results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
}
}

The class of primary importance here is the CSharpCodeProvider which utilises the compiler to compile code on the fly. If you want to then run the code, you just need to use a bit of reflection to dynamically load the assembly and execute it.

Here is another example in C# that (although slightly less concise) additionally shows you precisely how to run the runtime-compiled code using the System.Reflection namespace.

C# How to add a code to execute at Runtime

Searched for 'dynamic c# code execution' and Google came up with this blog from 2002... This might work for you..

http://www.west-wind.com/presentations/dynamiccode/dynamiccode.htm

The article refers to System.CodeDom.Compiler to compile a assembly on the fly and then using Reflection to execute that code. Sounds like fun ;)

EDIT: As DaveL suggested: Is it possible to dynamically compile and execute C# code fragments?

execute c# code at runtime from code file

You can use Microsoft.CSharp.CSharpCodeProvider to compile code on-the-fly. In particular, see CompileAssemblyFromFile.

Is it possible to create/execute code in run-time in C#?

Absolutely - that's exactly what I do for Snippy for example, for C# in Depth. You can download the source code here - it uses CSharpCodeProvider.

There's also the possibility of building expression trees and then compiling them into delegates, using DynamicMethod, or the DLR in .NET 4... all kinds of things.

How does one run code within the browser at Run-time

Suchiman / Robin Sue is has integrated the Monaco editor as well as an in-browser C# compiler in this nifty blazor project (live demo)

Executing C# or VB.NET code at Runtime

Have a look at http://msdn.microsoft.com/en-us/library/system.codedom.compiler.aspx Executing such code in a web app is in deed a security problem. .Net provides a set of functionalities to help you solve that problem, like the possibility to run your compiled code in a different app domain as a different user.

Codegeneration at runtime from a string to console exe is not working in C# .NET6

It is not possible to codegenerate directly a console application like the initial approach above. One possible solution is to generate first a dll (what I mentioned above in the example code is working fine), and from there include that .dll into a .exe, from where the functionality can run.



Related Topics



Leave a reply



Submit