2016-04-27 3 views
0

Ich habe eine Anwendung, in der ich die Roslyn-Skript-Engine (Namespace Microsoft.CodeAnalysis.Scripting) verwenden.Wie kann man auf Globals in der Roslyn Scripting-Umgebung zugreifen und sie bearbeiten?

Was habe ich jetzt dies:

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

Um es klar: In meiner app, gibt es ein bestimmtes Ereignis. Der Benutzer kann definieren, was passiert, wenn das Ereignis mit einem C# -Code auftritt (dieser Code wird häufig geändert). Jetzt ist der Punkt - ich muss Ereignisargumente an das Skript übergeben, damit der Benutzer es im Code verwenden kann. Gleichzeitig muss ich den Motorzustand beibehalten, da der Benutzer einige Variablen definiert haben könnte, die er beim nächsten Mal verwenden möchte.

Ich kann bereits übergeben die Ereignisargumente (und beziehen Sie sich wie e im Skript), aber nur zum ersten Mal (d. H. Wenn die ScriptState ist null und ich eine neue erstellen). Das nächste Mal, wenn dieses oder ein anderes Skript ausgeführt wird (ScriptState.ContinueWithAsync), sind die Ereignisargumente die gleichen wie im vorherigen Zustand, da ich keine Möglichkeit kenne, sie zu aktualisieren.

Wie erreiche ich die globale e und setze sie auf einen neuen Wert? Ich habe bereits versucht, über die Variables Liste darauf zuzugreifen (wie Sie im Code sehen können), aber es scheint, dass Globals nicht in der Liste gehalten werden. Gleichzeitig kann ich beim Ausführen des ersten Skripts keine Variablen hinzufügen, da die Klasse ScriptVariable einen internen Konstruktor hat. (ScriptState.Variables.Add(ScriptVariable))

Danke für die Hilfe. Ich hoffe, ich habe mich selbst artikuliert, sicher sein, in Kommentaren alles zu fragen.

Antwort

4

Sie können das Original e Referenz aktualisieren:

 
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; 
} 
+0

Omg. Warum habe ich das nicht versucht ?! Danke, funktioniert :) – Sorashi