扩展 C# .NET 应用程序 - 是不是构建自定义脚本语言?

Posted

技术标签:

【中文标题】扩展 C# .NET 应用程序 - 是不是构建自定义脚本语言?【英文标题】:Extending C# .NET application - build a custom scripting language or not?扩展 C# .NET 应用程序 - 是否构建自定义脚本语言? 【发布时间】:2010-11-22 10:23:38 【问题描述】:

我需要为我的 C# 程序构建一个脚本接口,用于对嵌入式固件进行系统级测试。

我的应用程序包含与设备完全交互的库。有单独的库用于启动操作、获取输出和跟踪成功/失败。我的应用程序还有一个 GUI,用于管理多个设备并分配许多要运行的脚本。

对于测试人员(非程序员,但技术人员),我需要提供一个脚本接口,使他们能够提出不同的测试场景并运行它们。他们只是要调用我的 API,然后将结果返回给我的程序(通过/失败和消息)。

我想要的一个非常基本的例子:

TURN_POWER_ON
TUNE_FREQUENCY frequency
WAIT 5
IF GET_FREQUENCY == frequency
  REPORT_PASS "Successfully tuned to " + frequency
ELSE
  REPORT_FAIL "Failed to tune to " + frequency
ENDIF
TURN_POWER_OFF

报告、功率和频率函数由我的 C# 库提供。

IronRuby 或 IronPython 之类的东西会对此有好处吗,还是我应该构建自己的非常基本的语言?

在尝试包含一堆 .NET 编译的程序集时,Ruby/Python 代码是否会变得混乱?我希望它对非程序员和程序员一样易于学习和编码。

编辑:

感谢所有精彩的回复。我选择 IronPython 作为答案,因为它得到了最多的支持,但我会花一些时间来了解 IronPython、Boo 和 IronRuby 中的每一个,看看测试人员更喜欢用什么来编写脚本。

【问题讨论】:

【参考方案1】:

我听说 IronPython 非常适合正是这种类型的场景。我肯定会冒险花几个小时进行快速的概念验证,看看结果如何。

Michael Foord 会很高兴地对 IronPython 在类似情况下的成功进行抒情(尤其是对他而言,对于精通电子表格的用户),his book 涵盖 (IIRC) 关于从 .NET 托管它的一些建议。

【讨论】:

太好了 :) 这种集成有什么好的例子/教程吗?我很想看看类似这样的最终 Python 代码是什么样的。 我很确定 IronPython In Action 涵盖了一些(尽管它可能已经过时了);你可以看这里:blogs.msdn.com/srivatsn/archive/2008/09/16/… 我在我的博客gotnet.biz/Blog/post/… 上有一个示例,展示了如何使用 Python 编写 C#(或 VB.NET)脚本【参考方案2】:

您可能想查看Boo,这是另一种在 CLR 上运行的托管语言,它特别适合构建 DSL 并使您的应用程序可编写脚本。

编译管道可以直接从语言本身扩展。

如果您想了解更多信息,阅读Boo Manifesto 是一个很好的起点。

[编辑]我忘了提到Ayende Rahien正在写一本关于这个主题的完整书: Building Domain Specific Languages in Boo

【讨论】:

【参考方案3】:

对于此类任务,可能值得考虑使用 PowerShell。这可以像任何 DLR 语言一样调用 .Net,并且在其 cmdlet(command-let)概念中为任务提供更自然的语言类型分块。您必须在 v1 中以编译语言编写 cmdlet——在 v2 中,该版本从 Win7 开始推出,并在接下来的几个月内适用于旧版本(Vista/Win2k8 的 v2 现在在 RC),您可以构建这些直接在 PowerShell 中。

【讨论】:

【参考方案4】:

我同意 Marc G 的观点,但值得一提的是,一般概念是域特定语言。虽然 IronRuby/IronPython 不是严格特定于领域的,但它们功能齐全,可以让您继续实施。

Visual Studio 有 DSL 工具,还有你可以研究的“M”语法。

但是,是的,IronPython。

【讨论】:

我每天都在学习一个新的首字母缩写词……DSL 现在出现在我的词汇表中(两次)。谢谢,你已经帮助我的谷歌搜索了很多:)【参考方案5】:

根据您要使用的 DSL,我建议将 CUCUMBER 与 IronRuby 一起使用。

使用 Cucumber,测试人员可以编写如下所示的测试:

Scenario: See all vendors
Given I am logged in as a user in the administrator role
And There are 3 vendors
When I go to the manage vendors page
Then I should see the first 3 vendor names

使这种语言适合您的需求非常容易。 只需 google 一下“Cucumber and IronRuby”,您就会找到一些指南和博客文章来帮助您入门。

【讨论】:

【参考方案6】:

我们在我们的一个项目中使用嵌入式 Iron Python 来制定定价公式。这是真实样本的外观。

E_DOCUMENT_CHECK = DCPAV * ADS_NUM
E_SPECIFIC_TAX = STV
E_RESOURCE_DEV = RDV
E_LP_ISSUANCE = LPIV
E_ANNUAL_FEES = APFCV * SA * SIDES_NUM
E_SERVICE_FEES= MAX(
MINSFV,
E_DOCUMENT_CHECK+E_SPECIFIC_TAX+E_RESOURCE_DEV+E_LP_ISSUANCE+E_ANNUAL_FEES)
TOTAL= E_DOCUMENT_CHECK+E_SPECIFIC_TAX+E_RESOURCE_DEV+E_LP_ISSUANCE+E_ANNUAL_FEES+E_SERVICE_FEES

实现起来非常简单。例如,Max() 函数只是我们导入 IronPython 引擎的自定义 C# 方法之一,在配置设置中使用它看起来很自然。

【讨论】:

这看起来真的很棒。你是如何让 MAX() 函数看起来如此原生于脚本的?我现在的问题是我不希望到处都是 .NET 样式的类。每个示例看起来都像 SomeClass.Max() 我只想要像你一样的基本脚本...... 如果您碰巧看到此评论,也许您可​​以在***.com/questions/1348188/… 为我的新/相关问题提供答案【参考方案7】:

您可以只使用 C# 本身作为脚本语言,如此处所述 CrowsProgramming - Runtime Scripting in .Net

【讨论】:

我过去做过这个,这真的不是我想要的。由于您需要使用 C# 样式语法声明至少一个类和一个成员函数,因此无法创建一个看起来像我使用 C# 的示例的脚本。 @Kiquenet,这很不幸。您仍然可以通过 Wayback Machine 访问它:web.archive.org/web/20150303092513/http://…【参考方案8】:

IronRuby 是创建特定领域语言的最强大的语言,因为它的语法比 python 的更灵活和宽容(你的用户会搞砸空格并被强制的 () 调用方法惹恼)。

您可以在 IronRuby 中编写示例脚本,它看起来像这样:

TURN_POWER_ON
TUNE_FREQUENCY frequency
WAIT 5
if GET_FREQUENCY == frequency
  REPORT_PASS "Successfully tuned to " + frequency
else
  REPORT_FAIL "Failed to tune to " + frequency
end
TURN_POWER_OFF

这是我们的测试人员目前用来针对我们的 UI 编写自动化测试的 DSL 示例

window = find_window_on_desktop "OurApplication"
logon_button = window.find "Logon"
logon_button.click

list = window.find "ItemList"
list.should have(0).rows

add_button = window.find "Add new item"
add_button.click
list.should have(1).rows

但是,就目前的情况而言,IronPython 比 IronRuby 成熟得多,性能也好得多,所以您可能更喜欢使用它。

我强烈建议您使用 IronPython 或 IronRuby,而不是创建您自己的自定义语言...您将节省难以想象的工作量(和错误)

【讨论】:

感谢您的回答。我个人想使用 IronRuby(用于无括号语法),但 IronPython 的成熟度最终胜出。两者都是不错的选择,但我在最初的测试阶段遇到了 IronRuby 的更多问题。【参考方案9】:

讽刺也可能是一个很好的候选人。 这是一个为给定图像动态创建动画的示例。

Set camera size: 400 by 300 pixels.
Set camera position: 100, 100.
Move 200 pixels right.
Move 100 pixels up.
Move 250 pixels left.
Move 50 pixels down.

创建此类 DSL 的教程在这里:Writing Your First Domain Specific Language

这是一个旧教程,但作者仍然在这里维护他的库:Github Irony

【讨论】:

以上是关于扩展 C# .NET 应用程序 - 是不是构建自定义脚本语言?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 为 Windows 构建 AIR 本机扩展?

构建 .NET 包装器是不是需要源代码?

C# (.NET) 的无头浏览器? [关闭]

.net:C#的委托

构建具有多个视图的 C# .NET windows 应用程序

.NET 的 Node.js