传递对象实例罗斯林的ScriptEngine实例、对象、罗斯林、ScriptEngine

2023-09-03 06:46:44 作者:十柒.

我在寻找一个C#脚本引擎,可以跨preT的C#code块,而维修器材上下文。例如,如果输入到它: VAR一个= 1; ,然后 A + 3 ,它会输出 4 。 我知道MS 罗斯林的 ,这的确做到这一点,但它是一个沙盒(关于启动它的程序)。所以,如果我创建的ScriptEngine 的实例,实例 MyClass的(只是一个arbirary类矿井),我别无选择,通过了 my_class 引用 script_engine

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 a + 3, it'll output 4. I'm aware of MS Roslyn , which indeed do that, but it's a sandbox (respect to the program that launched it). So, if I create an instance of ScriptEngine and an instance of MyClass (just an arbirary class of mine) , I have no option to pass a reference of my_class to script_engine.

是否有可能以某种方式传递引用

Is it possible to somehow pass that reference?

什么的我想的做的,是一样的东西:

What I'd like to do, is something like:

ScriptEngine engine; // A Roslyn object
Session session // A Roslyn object

MyClass my_class; // My object

// all required initializations

Submission<object> sm = session.CompileSubmission<object>("var a=1;"); 
dynamic result = sm.Execute(); 

Submission<object> sm = session.CompileSubmission<object>("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<object> sm = session.CompileSubmission<object>("my_class.ToString();"); 
dynamic result = sm.Execute();  // result is no the output of my_class.ToString()

请注意, AddReferenceToAnOject()是缺少的一部分,有罗斯林没有这样的功能。

Please notice that AddReferenceToAnOject() is the missing part, as there's no such function in roslyn.

推荐答案

答案被发现在一个链接的评论由@Herman。

The answer was found in a link commented by @Herman.

由于转出,罗斯林的ScriptEngine /会话支持主机对象的概念。 为了使用它,定义一个类你的choise的,并且在会话创建通过。这样做,使该主机对象的所有的公开的成员,提供给上下文会话内:

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