将对象实例传递给Roslyn ScriptEngine

我正在寻找一个C#脚本引擎,它可以解释C#代码块,同时维护一个上下文。 例如,如果输入它: var a = 1; ,然后a + 3 ,它将输出4 。 我知道MS Roslyn ,确实这样做,但它是一个沙箱(尊重启动它的程序)。 所以,如果我创建一个ScriptEngine实例和一个MyClass实例(只是我的一个arbirary类),我没有选择将my_class的引用my_classscript_engine

有可能以某种方式传递该引用吗?

我想做的是:

 ScriptEngine engine; // A Roslyn object Session session // A Roslyn object MyClass my_class; // My object // all required initializations Submission sm = session.CompileSubmission("var a=1;"); dynamic result = sm.Execute(); Submission sm = session.CompileSubmission("a + 3;"); dynamic result = sm.Execute(); // result is now 4 MyClass my_class; session.AddReferenceToAnOject(my_class); // function that does not exists, but reflect my intention Submission sm = session.CompileSubmission("my_class.ToString();"); dynamic result = sm.Execute(); // result is no the output of my_class.ToString() 

请注意AddReferenceToAnOject()是缺少的部分,因为roslyn中没有这样的function。

答案在@Herman评论的链接中找到。

事实certificate,Roslyn ScriptEngine/Session支持Host Object的概念。 为了使用它,定义一个选择的类,并在创建会话时传递它。 这样做,使该主机对象的所有公共成员可用于会话内的上下文:

 public class MyHostObject { public List list_of_ints; public int an_int = 23; } var hostObject = new MyHostObject(); hostObject.list_of_ints = new List(); 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); 

这是一个完整的过程,如何将变量从object传递给roslyn动态执行代码。 包含的还有eval()包装器。 首先从microsoft.com安装RoslynSetup.exe http://www.microsoft.com/en-sa/download/details.aspx?id=34685

然后将参考Roslyn.Compilers和Roslyn.Compilers.CSharp添加到您的项目(程序集/扩展)

这是vs2012中C#console app的完整工作代码。

 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(tr); e.eval("Test = Test + \" AND THIS WAS SET FROM Eval()\";"); System.Console.WriteLine(tr.Test); string a = e.eval("string a = \"return this from eval\";a"); System.Console.WriteLine(a); tr.Test = "now return this"; string b = e.eval("string a = Test + \" ... and this\";a"); System.Console.WriteLine(b); double d = e.eval("double dbl = 1.2345*3;dbl"); System.Console.WriteLine(d); e.eval("string testIt(string a){return \"testIt(): \"+a+\"\";}"); string c = e.eval("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 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(string strEval) { return (T) Session.Execute(strEval); } } }