使用IronPython简化为C#应用程序编写的DSL

时间:2009-08-28 16:44:51

标签: c# .net ironpython dsl

感谢previous question的建议,我正忙着尝试使用IronPython,IronRuby和Boo为我的C#应用​​程序创建一个DSL。由于更大的用户和知识库,第一步是IronPython。如果我能在这里找到合适的东西,我可以停下来。

这是我的问题:

我希望我的IronPython脚本能够访问名为Lib的类中的函数。现在我可以将程序集添加到IronPython运行时并通过执行我创建的作用域中的语句来导入该类:

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

如果我想运行Lib :: PrintHello,这只是一个hello world样式语句,我的Python脚本包含:

Lib.PrintHello()

或(如果它不是静态的):

library = new Lib()
library.PrintHello()

如何更改我的环境,以便我可以在Python脚本中获得基本的语句,如下所示:

PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...

我希望这些脚本对于非程序员来说很简单。我不希望他们必须知道课程是什么或它是如何工作的。 IronPython真的就在那里,所以像for,do,if和基本函数定义这样的基本操作不需要我为我的DSL编写编译器。

1 个答案:

答案 0 :(得分:19)

您应该可以执行以下操作:

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

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

这将从lib objec中获取所有成员,然后将它们注入ScriptScope。这是通过Python ObjectOperations类完成的,这样你下载的成员就是Python成员。因此,如果您使用IronRuby执行类似的操作,则相同的代码应该基本上可以正常工作。