Scripting API Samples - PeterMortensen/roslyn GitHub Wiki
The scripting APIs enable .NET applications to instatiate a C# engine and execute code snippets against host-supplied objects. Below are examples of how to get started with the scripting APIs and some common samples. You can also view the Scripting API source code.
Scripting APIs require desktop .NET Framework 4.6 or CoreCLR 1.0.
Scripting APIs can't be used within Universal Windows Applications and .NET Native since the application model doesn't support code compilation at runtime.
Install the Scripting API NuGet Package:
Install-Package Microsoft.CodeAnalysis.Scripting
Using your text editor of choice, create a csx file. To run your script, use the command-line tool csi.exe. If you have Visual Studio installed you can access csi.exe via the Developer Command Prompt. If you do not have Visual Studio installed on your machine, you can access csi.exe with the dotnet CLI tool.
To run a script file simply type the command:
csi "MyScript.csx"
Note: the samples require the following using:
using Microsoft.CodeAnalysis.CSharp.Scripting;
- Evaluate a C# expression
- Evaluate a C# expression (strongly-typed)
- Evaluated a C# expression with error handling
- Add references
- Add imports
- Parameterize a script
- Create & build a C# script and execute it multiple times
- Create a delegate to a script
- Run a C# snippet and inspect defined script variables
- Chain code snippets to form a script
- Continue script execution from a previous state
- Create and analyze a C# script
- Customize assembly loading
object result = await CSharpScript.EvaluateAsync("1 + 2");
int result = await CSharpScript.EvaluateAsync<int>("1 + 2");
try
{
Console.WriteLine(await CSharpScript.EvaluateAsync("2+2"));
}
catch (CompilationErrorException e)
{
Console.WriteLine(string.Join(Environment.NewLine, e.Diagnostics));
}
var result = await CSharpScript.EvaluateAsync("System.Net.Dns.GetHostName()",
ScriptOptions.Default.WithReferences(typeof(System.Net.Dns).Assembly));
var result = await CSharpScript.EvaluateAsync("Sqrt(2)",
ScriptOptions.Default.WithImports("System.Math"));
Note: there is a known bug here. A workaround would be to define Globals in a .dll and #r the .dll.
public class Globals
{
public int X;
public int Y;
}
var globals = new Globals { X = 1, Y = 2 };
Console.WriteLine(await CSharpScript.EvaluateAsync<int>("X+Y", globals: globals));
var script = CSharpScript.Create<int>("X*Y", globalsType: typeof(Globals));
script.Compile();
for (int i = 0; i < 10; i++)
{
Console.WriteLine(await script.RunAsync(new Globals { X = i, Y = i }));
}
The delegate doesn’t hold compilation resources (syntax trees, etc.) alive.
var script = CSharpScript.Create<int>("X*Y", globalsType: typeof(Globals));
ScriptRunner<int> runner = script.CreateDelegate();
for (int i = 0; i < 10; i++)
{
await runner(new Globals { X = i, Y = i });
}
var state = await CSharpScript.RunAsync<int>("int answer = 42");
foreach (var variable in state.Variables)
Console.WriteLine($"{variable.Name} = {variable.Value} of type {variable.Type}");
var script = CSharpScript.
Create<int>("int x = 1;").
ContinueWith("int y = 2;").
ContinueWith("x + y");
Console.WriteLine((await script.RunAsync()).ReturnValue);
var state = await CSharpScript.RunAsync("int x = 1;");
state = await state.ContinueWithAsync("int y = 2;");
state = await state.ContinueWithAsync("x+y");
Console.WriteLine(state.ReturnValue);
using Microsoft.CodeAnalysis;
var script = CSharpScript.Create<int>("3");
Compilation compilation = script.GetCompilation();
//do stuff
Compilation gives access to the full set of Roslyn APIs.
using Microsoft.CodeAnalysis.Scripting.Hosting;
using (var loader = new InteractiveAssemblyLoader())
{
var script = CSharpScript.Create<int>("1", assemblyLoader: loader);
//do stuff
}