I\'m looking for a C# scripting engine, that can interpret blocks of C# code, while maintaing a context. For example, if enter to it: var a = 1;
, and then
The answer was found in a link commented by @Herman.
As it turn out, Roslyn ScriptEngine/Session
supports a concept of Host Object
.
In order to use it, define a class of your choise, and pass it upon session creation. Doing so, makes all public member of that host object, available to context inside the session:
public class MyHostObject
{
public List<int> list_of_ints;
public int an_int = 23;
}
var hostObject = new MyHostObject();
hostObject.list_of_ints = new List<int>();
hostObject.list_of_ints.Add(2);
var engine = new ScriptEngine(new[] { hostObject.GetType().Assembly.Location });
// passing reference to hostObject upon session creation
var session = Session.Create(hostObject);
// prints `24` to console
engine.Execute(@"System.Console.WriteLine(an_int + list_of_ints.Count);",
session);
Here is a complete procedure how to pass variables from object to roslyn dynamic executed code. Included is also eval() wrapper. First install RoslynSetup.exe from microsoft.com http://www.microsoft.com/en-sa/download/details.aspx?id=34685
Then Add Reference Roslyn.Compilers and Roslyn.Compilers.CSharp to your project (Assemblies / extensions)
Here is full working code for C# console app in vs2012.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
using Roslyn.Scripting;
using Roslyn.Scripting.CSharp;
namespace testRoslyn
{
class Program
{
static void Main(string[] args)
{
TestRoslyn tr = new TestRoslyn();
tr.Test = "this was set from main program ";
tr.test();
System.Console.WriteLine(tr.Test);
tr.Test = "this was set from main program for eval";
Eval e = new Eval();
e.create<TestRoslyn>(tr);
e.eval("Test = Test + \" AND THIS WAS SET FROM Eval()\";");
System.Console.WriteLine(tr.Test);
string a = e.eval<string>("string a = \"return this from eval\";a");
System.Console.WriteLine(a);
tr.Test = "now return this";
string b = e.eval<string>("string a = Test + \" ... and this\";a");
System.Console.WriteLine(b);
double d = e.eval<double>("double dbl = 1.2345*3;dbl");
System.Console.WriteLine(d);
e.eval("string testIt(string a){return \"testIt(): \"+a+\"\";}");
string c = e.eval<string>("string c = testIt(\"nice\");c");
System.Console.WriteLine(c);
Console.ReadKey();
}
}
public class TestRoslyn
{
public string Test;
public TestRoslyn()
{
}
public string test()
{
ScriptEngine roslynEngine = new ScriptEngine();
Roslyn.Scripting.Session session = roslynEngine.CreateSession(this);
session.AddReference(this.GetType().Assembly);
session.AddReference("System.Web");
session.ImportNamespace("System");
session.ImportNamespace("System.Web");
var result = (string)session.Execute("Test = Test + \" ... and this was set from roslyn code.\";Test");
return result;
}
}
public class Eval
{
ScriptEngine RoslynEngine = new ScriptEngine();
Roslyn.Scripting.Session Session;
public void create<T>(T hostObject = null) where T : class
{
RoslynEngine = new ScriptEngine();
Session = RoslynEngine.CreateSession(hostObject);
if (hostObject != null)
Session.AddReference(hostObject.GetType().Assembly);
Session.AddReference("System.Web");
Session.ImportNamespace("System");
Session.ImportNamespace("System.Web");
}
public void eval (string strEval)
{
Session.Execute(strEval);
}
public T eval<T>(string strEval)
{
return (T) Session.Execute(strEval);
}
}
}