编写代码以自定义特定于域的语言

本部分介绍如何使用自定义代码在领域特定语言(DSL)中访问、修改或创建模型。

用于编写 DSL 代码的上下文

有几个上下文可用于编写适用于 DSL 的代码:

In-Memory Store

DslDefinition.dsl 中定义的类的实例保存在名为 In-Memory Store (IMS)或 Store 的数据结构中。 在 DSL 中定义的类始终将 Store 作为构造函数的参数。 例如,如果 DSL 定义了一个名为 Example

Example element = new Example (theStore);

将对象保留在应用商店中,而不是像普通对象一样,可提供多种优势。

  • Transactions。 可以将一系列相关更改分组成一个事务:

    using (Transaction t = store.TransactionManager.BeginTransaction("updates"))
    {
      // make several changes to Store elements here
      t.Commit();
    }
    

    如果在更改过程中发生异常,从而无法执行最终的 Commit(),则存储将重置为先前的状态。 此方法有助于确保错误不会使模型处于不一致状态。 有关详细信息,请参阅 在程序代码中导航和更新模型

  • 二进制关系。 如果定义两个类之间的关系,则两端的实例都有一个导航到另一端的属性。 两端始终同步。 例如,如果使用名为 ParentsChildren 的角色定义父母关系,则可以编写:

    John.Children.Add(Mary)

    以下两个表达式现在均为 true:

    John.Children.Contains(Mary)

    Mary.Parents.Contains(John)

    还可以通过编写来实现相同的效果:

    Mary.Parents.Add(John)

    有关详细信息,请参阅 在程序代码中导航和更新模型

  • 规则和事件。 可以定义在进行指定更改时触发的规则。 例如,规则用于使图表上的形状与它们存在的模型元素保持最新。 有关详细信息,请参阅 “响应和传播更改”。

  • 序列化。 Store 提供了一种标准方法,用于将它包含的对象序列化为文件。 可以自定义用于序列化和反序列化的规则。 有关详细信息,请参阅 自定义文件存储和 XML 序列化