编写代码以自定义域特定语言
本部分介绍如何使用自定义代码以域特定的语言 (DSL) 访问、修改或创建模型。
用于为 DSL 编写代码的上下文
可以在多种上下文中编写使用 DSL 的代码:
自定义命令。 你可以创建一个可修改模型的命令,用户可通过右键单击图表来调用该命令。 有关详细信息,请参阅如何:向快捷菜单添加命令。
验证。 可以编写代码来验证模型是否处于正确状态。 有关详细信息,请参阅域特定语言中的验证。
重写默认行为。 可以对从 DslDefinition.dsl 生成的代码的许多部分进行修改。 有关详细信息,请参阅重写和扩展生成的类。
文本转换。 可以编写文本模板,其中包含可访问模型且可生成文本文件的代码,用于生成程序代码等。 有关详细信息,请参阅从域特定语言生成代码。
其他 Visual Studio 扩展。 可以编写单独的 VSIX 扩展来读取和修改模型。 有关详细信息,请参阅如何:从程序代码中的文件打开模型
内存中存储
DslDefinition.dsl 中定义的类的实例保存在称为 In-Memory Store (IMS) 或 Store 的数据结构中。 DSL 中定义的类始终将 Store 作为构造函数的参数。 例如,如果 DSL 定义了一个名为 Example
的类:
Example element = new Example (theStore);
将对象保存在 Store 中(而不是像普通对象一样保存)具有多个好处。
Transactions。 可以将一系列相关更改分组到一个事务:
using (Transaction t = store.TransactionManager.BeginTransaction("updates")) { // make several changes to Store elements here t.Commit(); }
如果更改过程中发生异常,导致最终的
Commit()
没有执行,Store 会重置为先前的状态。 此方法有助于确保错误不会导致模型处于不一致状态。 有关详细信息,请参阅在程序代码中导航和更新模型。二进制关系。 如果定义两个类之间的关系,则两端的实例都具有一个可导航到另一端的属性。 这两端始终同步。 例如,如果使用名为“Parents”和“Children”的角色定义父子级关系,可以编写以下内容:
John.Children.Add(Mary)
以下两个表达式现在都为 true:
John.Children.Contains(Mary)
Mary.Parents.Contains(John)
也可以通过编写以下内容来达到同样的效果:
Mary.Parents.Add(John)
有关详细信息,请参阅在程序代码中导航和更新模型。
规则和事件。 可以定义在进行指定更改时触发的规则。 例如,指定规则使图表上的形状与其呈现的模型元素保持同步。 有关详细信息,请参阅响应和传播更改。
序列化。 Store 提供了一种将其包含的对象序列化到文件中的标准方法。 可以自定义序列化和反序列化的规则。 有关详细信息,请参阅自定义文件存储和 XML 序列化。