本部分介绍如何使用自定义代码在领域特定语言(DSL)中访问、修改或创建模型。
用于编写 DSL 代码的上下文
有几个上下文可用于编写适用于 DSL 的代码:
- 自定义命令。 可以创建一个命令,用户可以通过右键单击关系图来调用该命令,并可以修改模型。 有关详细信息,请参阅 How to: Add a Command to the Shortcut Menu. 
- 验证。 可以编写代码来验证模型是否处于正确状态。 有关详细信息,请参阅 Domain-Specific 语言中的验证。 
- 覆盖默认行为。 可以修改从 DslDefinition.dsl 生成的代码的许多方面。 有关详细信息,请参阅 重写和扩展生成的类。 
- 文本转换。 可以编写包含访问模型并生成文本文件的代码的文本模板,例如生成程序代码。 有关详细信息,请参阅 从 Domain-Specific 语言生成代码。 
- 其他 Visual Studio 扩展。 可以编写单独的 VSIX 扩展来读取和修改模型。 有关详细信息,请参阅 如何:在程序代码中从文件打开模型 
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(),则存储将重置为先前的状态。 此方法有助于确保错误不会使模型处于不一致状态。 有关详细信息,请参阅 在程序代码中导航和更新模型。
- 二进制关系。 如果定义两个类之间的关系,则两端的实例都有一个导航到另一端的属性。 两端始终同步。 例如,如果使用名为 Parents 和 Children 的角色定义父母关系,则可以编写: - John.Children.Add(Mary)- 以下两个表达式现在均为 true: - John.Children.Contains(Mary)- Mary.Parents.Contains(John)- 还可以通过编写来实现相同的效果: - Mary.Parents.Add(John)- 有关详细信息,请参阅 在程序代码中导航和更新模型。 
- 规则和事件。 可以定义在进行指定更改时触发的规则。 例如,规则用于使图表上的形状与它们存在的模型元素保持最新。 有关详细信息,请参阅 “响应和传播更改”。 
- 序列化。 Store 提供了一种标准方法,用于将它包含的对象序列化为文件。 可以自定义用于序列化和反序列化的规则。 有关详细信息,请参阅 自定义文件存储和 XML 序列化。