10 Stimmen

Vereinfachung der für eine C#-Anwendung geschriebenen DSL mit IronPython

Dank der Vorschläge eines vorherige Frage Ich bin damit beschäftigt, IronPython, IronRuby und Boo auszuprobieren, um eine DSL für meine C#-App zu erstellen. Schritt eins ist IronPython, aufgrund der größeren Benutzer- und Wissensbasis. Wenn ich etwas zu bekommen, um gut zu arbeiten hier, ich kann einfach aufhören.

Hier ist mein Problem:

Ich möchte, dass mein IronPython-Skript Zugriff auf die Funktionen in einer Klasse namens Lib hat. Im Moment kann ich die Assembly zur IronPython-Laufzeit hinzufügen und die Klasse importieren, indem ich die Anweisung in dem von mir erstellten Bereich ausführe:

// load 'ScriptLib' assembly
Assembly libraryAssembly = Assembly.LoadFile(libraryPath);
_runtime.LoadAssembly(libraryAssembly);

// import 'Lib' class from 'ScriptLib'
ScriptSource imports = _engine.CreateScriptSourceFromString("from ScriptLib import Lib", SourceCodeKind.Statements);
imports.Execute(_scope);

// run .py script:
ScriptSource script = _engine.CreateScriptSourceFromFile(scriptPath);
script.Execute(_scope);

Wenn ich Lib::PrintHello ausführen möchte, was nur eine Anweisung im Stil von Hallo Welt ist, enthält mein Python-Skript:

Lib.PrintHello()

oder (wenn sie nicht statisch ist):

library = new Lib()
library.PrintHello()

Wie kann ich meine Umgebung so ändern, dass ich im Python-Skript nur grundlegende Angaben wie diese machen kann?

PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...

Ich möchte, dass diese Skripte für einen Nicht-Programmierer einfach zu schreiben sind. Ich will nicht, dass sie wissen müssen, was eine Klasse ist oder wie sie funktioniert. IronPython ist wirklich nur dazu da, damit einige grundlegende Operationen wie for, do, if und eine grundlegende Funktionsdefinition nicht erfordern, dass ich einen Compiler für meine DSL schreibe.

20voto

Dino Viehland Punkte 6428

Sie sollten in der Lage sein, etwas zu tun wie:

var objOps = _engine.Operations;
var lib = new Lib();

foreach (string memberName in objOps.GetMemberNames(lib)) {
    _scope.SetVariable(memberName, objOps.GetMember(lib, memberName));
}

Dadurch werden alle Member aus dem Lib-Objekt abgerufen und in das ScriptScope injiziert. Dies geschieht mit der Python ObjectOperations-Klasse, so dass die Mitglieder, die Sie erhalten, werden Python-Mitglieder sein. Wenn Sie also etwas Ähnliches mit IronRuby machen, sollte derselbe Code grundsätzlich funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X