如何在 Roslyn 脚本环境中访问和编辑全局变量? [英] How to access and edit globals in Roslyn scripting environment?
问题描述
我有一个使用 Roslyn 脚本引擎的应用程序(命名空间 Microsoft.CodeAnalysis.Scripting
).
我现在拥有的是:
public static async Task
为了更清楚:在我的应用程序中,有一个特定的事件.用户可以使用一些 C# 代码定义当事件发生时会发生什么(此代码经常更改).现在的重点是 - 我需要将事件参数传递给脚本,以便用户可以在代码中使用它.同时,我需要保持引擎状态,因为用户可能已经定义了一些他想要下次使用的变量.
我已经可以传递事件参数(并在脚本中像 e
一样引用它),但只是第一次(即当 ScriptState
为 null 并且我创建了一个新的).下次运行此脚本或其他脚本时 (ScriptState.ContinueWithAsync
),事件参数与前一个状态中的相同,因为我不知道如何更新它们.
如何访问 e
全局并将其设置为新值?我已经尝试通过 Variables
列表访问它(如您在代码中所见),但似乎全局变量并未保留在列表中.同时我在运行第一个脚本时不能添加任何变量,因为 ScriptVariable
类有一个内部构造函数.(ScriptState.Variables.Add(ScriptVariable)
)
感谢您的帮助.我希望我已经阐明了自己,请务必在评论中提出任何问题.
可以更新原e
参考:
I have an application in which I use the Roslyn scripting engine (namespace Microsoft.CodeAnalysis.Scripting
).
What I have right now is this:
public static async Task<object> Execute(string code, CommandEventArgs e)
{
if (_scriptState == null)
{
var options = ScriptOptions.Default;
options
.AddReferences(typeof (Type).Assembly,
typeof (Console).Assembly,
typeof (IEnumerable<>).Assembly,
typeof (IQueryable).Assembly)
.AddImports("System", "System.Numerics", "System.Text", "System.Linq", "System.Collections.Generics",
"System.Security.Cryptography");
_scriptState = await CSharpScript.RunAsync(code, options, new MessageGlobal {e = e});
}
else
{
// TODO: set global e (it's not in this variables list, thus it throws null reference)
_scriptState.GetVariable("e").Value = e;
_scriptState = await _scriptState.ContinueWithAsync(code);
}
return !string.IsNullOrEmpty(_scriptState.ReturnValue?.ToString()) ? _scriptState.ReturnValue : null;
}
To make it more clear: In my app, there is a certain event. User can define what happens when the event occurs with some C# code (this code is being changed frequently). Now the point is - I need to pass event args to the script, so the user can use it in the code. In the same time, I need to keep the engine state, since the user could have defined some variables, which he wants to use the next time.
I already can pass the event args (and refer to it like e
in the script), but only for the first time (i.e. when the ScriptState
is null and I create a new one). The next time this or some other script is ran (ScriptState.ContinueWithAsync
), the event args are the same as in the previous state, because I don't know any way to update them.
How can I reach the e
global and set it to a new value? I've already tried to access it (as you can see in the code) through the Variables
list, but it seems that globals aren't kept in the list. At the same time I can't add any variable when running the first script, because the ScriptVariable
class has an internal constructor. (ScriptState.Variables.Add( ScriptVariable )
)
Thanks for the help. I hope I've articulated myself, be sure to ask anything in comments.
You can update the original e
reference:
public class Globals { public int E; } static void Main() { var globals = new Globals { E = 1 }; var _scriptState = CSharpScript.RunAsync("System.Console.WriteLine(E)", globals: globals).Result; globals.E = 2; var x = _scriptState.ContinueWithAsync("System.Console.WriteLine(E)").Result; }
这篇关于如何在 Roslyn 脚本环境中访问和编辑全局变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!