6

目前我正在使用的项目没有完全固定的模型(由于外部影响),因此我希望在编写它们时有一些灵活性。目前,它们在应用程序的三个不同层(db、web api 和客户端)中复制,并且每个层都有相似的逻辑(即验证)。

我想知道是否有一种方法可以让我编写模型文件(比如在 ruby​​ 中),然后让它将该模型转换为必要的 c# 文件。目前,我似乎只是在编写许多可能在任何阶段发生变化的样板代码,而这种生成的方法将使我能够专注于更重要的事情。

有没有人推荐这样的东西,我可以用的 dsl/语言,有没有人有这样的经验?

4

3 回答 3

5

我见过一个使用部分类和部分方法来允许重新生成代码而不影响自定义代码的系统。如果您愿意,“规则引擎”完全是从 Visio 状态图生成的。这基本上是糟糕的工作流程,但很容易修改。Viso 图表导出为 XML,使用 powershell 和 T4 读取 XML 以生成类。

上面的例子是一个外部 DSL。IE 在运行应用程序的编程语言之外。另一方面,您可以创建一个内部 DSL,该 DSL 在编程语言中实现和使用。

这篇和 Code-Magazine 上一篇关于 DSLS的文章都非常好。

在上面的链接中,Neal Ford 向您展示了如何使用流利的接口在 C# 中创建内部 DSL。

他还没有提到的一件事是你可以把这个属性 [EditorBrowsable(EditorBrowsableState.Never)] 放在你的方法上,这样它们就不会被智能感知。这意味着您可以对 DSL 的用户隐藏类上的非 DSL(如果您愿意的话)方法,从而使 fluent API 更容易被发现。

您可以在Daniel Cazzulino编写的关于使用 TDD 编写 IoC 容器的视频系列中看到流畅的界面正在实时编写

关于外部 DSL,您还可以选择Oslo(目前是 CTP),它非常强大,可以让您创建可以直接执行的外部 DSL,而不是使用想到的代码生成它根本不是一个 DSL。

于 2009-03-19T07:20:06.987 回答
5

这可以通过ANTLR轻松完成。如果输出足够相似,您可以简单地使用文本模板机制——否则它可以生成一个抽象语法树供您遍历。

于 2009-03-20T22:04:28.110 回答
1

我认为你在正确的轨道上。

在这种情况下,我通常做的是设计一种简单的语言来满足我的需求,并为它编写一个 LL1(递归下降)解析器。

如果该语言必须包含非平凡的 C# 语法,我可以引用它,或者将其包裹在我可以识别的括号中,然后将其传递给输出代码。

我可以让它生成一个解析树结构,然后从中生成 3 种不同类型的代码,或者我可以让它动态生成代码,或者使用具有 3 个值的模式变量,或者只是同时将代码写入 3不同的输出文件。

有不止一种方法可以做到这一点。如果您害怕编写解析器(就像某些程序员一样),那么在 SO 的其他地方有很多帮助。

于 2009-03-20T21:51:55.363 回答