Forked from Yukinii/RoslynScriptingCSharpTestSample.cs
Created
January 19, 2018 12:44
-
-
Save jrgcubano/a643c05629a10e587dd5ff58e6d0b504 to your computer and use it in GitHub Desktop.
Roslyn C# Scripting with Cache
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Threading.Tasks; | |
using Microsoft.CodeAnalysis.Scripting; | |
using Microsoft.CodeAnalysis.Scripting.CSharp; | |
namespace RoslynScriptingTest | |
{ | |
/// <summary> | |
/// Pure sample code. No exception handling. (Syntax errors in scripts throw exceptions at RunAsync()) | |
/// </summary> | |
public static class ScriptEngine | |
{ | |
public static readonly Dictionary<string,Script> Scripts = new Dictionary<string, Script>(); | |
private static IEnumerable<Assembly> _references; | |
/// <summary> | |
/// Executes and caches a script. Returns true if executed cached script. | |
/// </summary> | |
/// <param name="code">C# code to execute</param> | |
/// <returns>false if it had to be compiled. true if it had a cached version</returns> | |
public static async Task<bool> ExecuteAsync(string code) | |
{ | |
if (Scripts.ContainsKey(code)) | |
{ | |
await Scripts[code].RunAsync(); | |
return true; | |
} | |
var script = CSharpScript.Create(code, GetScriptOptions()); | |
await script.RunAsync(); | |
Scripts.Add(code, script); | |
return false; | |
} | |
/// <summary> | |
/// Forces building/compilation of the code you pass it. Caches the script for faster execution. | |
/// </summary> | |
/// <param name="code">C# code to compile and cache</param> | |
public static void PreCompile(string code) | |
{ | |
var script = CSharpScript.Create(code, GetScriptOptions()); | |
script.Build(); | |
Scripts.Add(code, script); | |
} | |
/// <summary> | |
/// Extendable function to setup script options. Currently adding all referenced assemblies to the script engine. | |
/// </summary> | |
/// <returns>ScriptOptions with all currently loaded assemblies</returns> | |
private static ScriptOptions GetScriptOptions() | |
{ | |
if(_references == null) | |
_references = AppDomain.CurrentDomain.GetAssemblies().Where(assembly=> assembly.Location != string.Empty); | |
return ScriptOptions.Default.WithReferences(_references); | |
} | |
} | |
public static class Program | |
{ | |
private static void Main() | |
{ | |
Task.Run(async () => | |
{ | |
Console.WriteLine("Test #1 - Executing same code twice. Should return: false, true"); | |
Console.WriteLine("Cached: " + await ScriptEngine.ExecuteAsync(@"using System; Console.WriteLine(""Hello World"");")); | |
Console.WriteLine("Cached: " + await ScriptEngine.ExecuteAsync(@"using System; Console.WriteLine(""Hello World"");")); | |
Thread.Sleep(3000); | |
Console.WriteLine("Test #2 - Precompiling same code and executing twice. Should return: true, true"); | |
ScriptEngine.Scripts.Clear(); | |
ScriptEngine.PreCompile(@"using System; Console.WriteLine(""Hello World"");"); | |
Console.WriteLine("Cached: " + await ScriptEngine.ExecuteAsync(@"using System; Console.WriteLine(""Hello World"");")); | |
Console.WriteLine("Cached: " + await ScriptEngine.ExecuteAsync(@"using System; Console.WriteLine(""Hello World"");")); | |
}); | |
while (true) | |
{ | |
Console.ReadLine(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment