了解 DSL 代码

一个域特定语言 (DSL)解决方案生成可用于读取和 DSL 更新实例。 Visual Studio的 API。 此 API 在从 DSL 定义生成的代码中定义。 本主题介绍生成的 API。

示例解决方案:组件图

若要创建是大多数的源本主题中的示例的解决方案,创建从 组件模型 解决方案模板的一个 DSL。 这是显示的一个标准模板在中创建新的 DSL 解决方案。

备注

组件图 DSL 模板与 UML 组件图无关可使用创建体系结构菜单中 Visual Studio 旗舰版。在 新项目 对话框中,展开 其他项目类型 \Extensibility 然后单击 域特定语言设计器

,如果您不熟悉此解决方案模板,按 F5 和操作。 特别是通知您通过在元素上的端口工具创建端口,因此,您可以连接端口。

组件及相互连接的端口

DSL 解决方案的结构

Dsl 项目定义 DSL 的 API。 DslPackage 项目定义它如何与集成 Visual Studio。 您还可以将拥有项目,也可以包含从模型生成的代码。

Bb286947.collapse_all(zh-cn,VS.110).gif代码目录

大多数在这些项目中的代码从 Dsl\DslDefinition.dsl生成。 生成的代码在 Generated Code 文件夹。 若要查看个生成的文件,请在生成的 .tt 文件旁边的 [+]

建议您检查生成的代码帮助您了解 DSL。 若要查看生成的文件,请在解决方案资源管理器中展开 *.tt 文件。

*.tt 文件包含生成代码的很少。 相反,它们使用 <#include> 指令包含共享模板文件。 共享文件可以在找到 \Program Files\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\DSL SDK\DSL Designer\11.0\TextTemplates

当您添加拥有程序代码中 DSL 解决方案,将其添加在单独的文件中,在生成的代码文件夹之外。 您可能希望创建 Custom Code 文件夹。 (当您添加新的代码文件添加到自定义文件夹,请确保更正了初始代码主干的命名空间。)

强烈建议您不要直接编辑生成的代码,,因为编辑器将丢失,当您重新生成解决方案时。 相反,自定义 DSL:

  • 调整在 DSL 定义的许多参数。

  • 在单独的代码文件中写入分部类中,重写中定义的方法或继承,生成的类。 在某些情况下,必须设置类的 生成派生的二进制文件 选项在 DSL 定义的,要重写生成的方法。

  • 设置会导致生成的代码提供 “自己的代码的挂钩的在 DSL 定义的选项。

    例如,因此,如果设置字段类的 具有自定义构造函数 选项,然后生成解决方案,您将看到错误消息。 当双击这些错误消息之一,您将看到解释在生成的代码的注释代表自定义代码应提供。

  • 编写拥有文本模板生成代码特定于应用程序。 您可以使用包含文件共享到多个项目共有的模板的一部分,因此,您可以创建 Visual Studio 项目模板设置初始化拥有文件结构的项目。

在 DSL 生成的文件

以下生成的文件显示在 Dsl 项目。

文件名

说明

TheDslSchema.xsd

包含 DSL 的实例文件的架构。 该文件将复制到生成 (bin) 内容。 在安装 DSL 时,可以复制此文件添加到 \Program Files\Microsoft Visual Studio 11.0\Xml\Schemas ,以便模型文件可以验证。 有关更多信息,请参见 部署域特定语言解决方案

如果通过在 DSL 资源管理器的选项自定义序列化,该模式将相应地更改。 但是,因此,如果您编写拥有序列化代码,此文件可能不再表示实际模式。 有关更多信息,请参见 自定义文件存储和 XML 序列化

ConnectionBuilders.cs

连接生成器是创建关系的类。 它是在连接工具后的代码。 此文件包含类对每个连接工具。 它们的名称从域关系和连接工具的名称派生: 关系生成器和 ConnectorToolConnectAction。

(在组件解决方案示例,一个连接生成器调用 ConnectionBuilder,这是巧合,,因为域关系名为 Connection。)

关系。 关系Builder.Connect() 创建方法。 默认版本验证源和目标架构元素可接受,然后将实例化关系。 例如:

CommentReferencesSubject(sourceAccepted, targetAccepted);

每个生成器类从+中 连接生成器 部分的节点会在 DSL 资源管理器。 一个 Connect 方法可创建一个或多个之间的关系对域类。 每一对都是由链接定义的连接指令,则在 DSL 资源管理器中找到在生成器节点下。

例如,可以添加到链接连接关系的三种类型的每一个的指令在示例 DSL 的一个连接生成器。 这将提供用户提供唯一连接工具。 实例化关系的类型取决于用户选择的源和目标元素的类型。 若要添加链接联接指令,右击 " DSL Explorer 的一个生成器。

对运行编写自定义代码,在域关系的特定类型创建时,选择适当的链接连接指令在生成器节点下。 在 " 属性 " 窗口中,将 使用自定义联接。 重新生成解决方案,然后提供代码更正发生的错误。

对运行编写自定义代码,只要用户使用此连接工具,设置连接生成器的 是自定义的 属性。 可以提供决定的代码源元素是否允许,应对源和目标的特定组合是否允许,,以及更新到模型中,当连接时。 例如,时,才能在关系图,将不会创建一个循环您可以允许连接。 而不是单一关系链接,您可以实例化多个相关元素的更复杂的模式在源和目标之间的。

Connectors.cs

包含连接的类,是关系图元素通常表示引用关系。 每个类从在 DSL 定义的联接生成。 每个 connect 类从派生 BinaryLinkShape

若要使颜色和其他一些样式功能变量在运行时,右击在 DSL 定义关系图的类并指向 将显示

若要进行其他样式功能变量在运行时 (clr),请参见例如 TextFieldShapeElement

Diagram.cs

包含定义关系图的类。 它从 Diagram派生。

若要使颜色和其他一些样式功能变量在运行时,右击在 DSL 定义关系图的类并指向 将显示

此外,此文件包含 FixupDiagram 规则,响应,当一个新元素添加到设计时。 规则添加新形状并链接到该模型元素的形状。

DirectiveProcessor.cs

此指令处理器帮助用户编写 text 读取 DSL 的实例的模板。 指令处理器加载程序集 (DLL) DSL 的并且有效插入命名空间的 using 语句。 在 DSL 定义的这使得文本模板的代码使用类和关系。

有关更多信息,请参见从域特定语言生成代码创建自定义 T4 文本模板指令处理器

DomainClasses.cs

的域类实现自己定义,包括抽象类和模型根类。 它们从 ModelElement派生。

每个域类包含:

  • 属性定义和嵌套的处理程序为每个字段特性类。 您可以重写 OnValueChanging() 和 OnValueChanged()。 有关更多信息,请参见 域属性值更改处理程序

    在示例 DSL, Comment 类包含一个属性 Text 和处理程序类 TextPropertyHandler。

  • 此字段类参与关系的访问器属性。 (没有角色特性的嵌套类。)

    在示例 DSL, Comment 类具有访问器访问其父模型将嵌入的关系 ComponentModelHasComments。

  • 构造函数。 如果要重写这些设置,在域类的 具有自定义构造函数

  • 元素组原型 (EGP)处理程序方法。 这些是必需的用户是否可以 合并 (添加) 在此类实例上的另一个元素。 通常用户可通过以下方式从拖动元素工具或另一个形状,或者通过粘贴。

    在示例 DSL,输入端或输出端口可合并在元素上。 此外,元素和注释可以合并在模型中。

    组件类的 EGP 处理程序方法允许不是元素接受端口,但是,注释。 根模型类的 EGP 处理程序接受注释而不是元素,但是,端口。

DomainModel.cs

表示域模型的类。 它从 DomainModel派生。

说明说明
这与该模型的根类。

复制和删除关闭定义哪些其他元素应包括的,当元素复制或删除过程。 可以通过设置角色的 传播复制传播删除 属性控制此行为在每个关系的每一端。 如果希望值动态确定,可以重写关闭类的方法中编写代码。 有关更多信息,请参见如何:程序复制和粘贴行为 - 重定向

DomainModelResx.resx

它包含字符串 (如 DOMAIN 类的声明和属性、属性名称、工具箱标签、标准错误消息和能向用户显示的其他字符串。 它还包含工具图标和图形图像形状的。

此文件绑定到生成的程序集,并提供这些资源的默认值。 可通过创建包含资源的本地化版本的附属程序集本地化 DSL。 该版本,当 DSL 在与本地化的资源,区域性安装是使用。 有关更多信息,请参见 部署域特定语言解决方案

DomainRelationships.cs

两个元素间的每个链接在模型由域关系类的实例表示的。 任何关系类从 lElementLink派生,从 ModelElement而后者派生。 由于它是 ModelElement,关系的实例具有特性,并且可以是关系的源或目标。

HelpKeywordHelper.cs

提供使用的功能,当用户按 F1 键时。

MultiplicityValidation.cs

在指定 1..1 或 1. * 重数的关系角色,需要该关系至少一个实例的用户应该发出警告。 此文件为实现这些警告的验证约束。 嵌入的父级的 1..1 链接不会验证。

对于要执行的这些约束,必须设置一个在 编辑 \Validation 节点的 使用… 选项在 DSL 资源管理器。 有关更多信息,请参见 域特定语言中的验证

PropertiesGrid.cs

,仅当附加自定义类型描述符到字段的特性,此文件包含代码。 有关更多信息,请参见 自定义“属性”窗口

SerializationHelper.cs

  • 确保验证的方法两个元素不是由同一标记引用。 有关更多信息,请参见 自定义文件存储和 XML 序列化

  • SerializationHelper 类提供函数,用于常见由序列化类。

Serializer.cs

每个域类、关系、形状、连接、关系图和模型的序列化程序类。

许多这类功能可以由 DSL 资源管理器中设置控件在 XML 序列化行为下。

Shapes.cs

每个形状类的类在 DSL 定义。 形状从 NodeShape派生。 有关更多信息,请参见 自定义文件存储和 XML 序列化

若要重写操作生成的方拥有该分部类的方法,请将连接的 生成派生的二进制文件 在 DSL 定义。 用自己的代码中替换构造函数,请将 具有自定义构造函数

若要使颜色和其他一些样式功能变量在运行时,右击在 DSL 定义关系图的类并指向 将显示

若要进行其他样式功能变量在运行时 (clr),请参见例如 TextFieldShapeElement

ToolboxHelper.cs

通过安装组件组原型设置工具箱到元素工具。 ,当用户运行该工具时,这些原型的副本与目标元素合并。

可以重写 CreateElementPrototype() 定义创建若干对象的一个组的工具箱项。 例如,您可以定义项表示具有子组件的对象。 在更改代码后,重置 Visual Studio 的实验实例中清除工具箱缓存。

在 DslPackage 项目中生成的文件

DslPackage 耦合 DSL 模型为 Visual Studio shell,管理窗口、工具箱和菜单命令。 大多数类是派生的二进制文件,因此,您可以重写其任一方法。

文件名

说明

CommandSet.cs

是显示在关系图上的上下文菜单命令。 可以修改或添加到此设置。 此文件包含命令的代码。 Commands.vsct 文件取决于指令的位置菜单上的。 有关更多信息,请参见 编写用户命令和操作

Constants.cs

GUID。

DocData.cs

TheDslDocData 管理加载和保存方式向文件,并创建存储实例。

例如,因此,如果在数据库中保存 DSL 而不是文件中,可以重写 Load 和 Save 方法。

DocView.cs

TheDslDocView 管理图显示的窗口。 例如,可以嵌入在 windows 窗体中的关系图:

添加用户控件文件添加到 DslPackage 项目。 添加关系图上显示的面板。 添加按钮和其他控件。 在窗体的代码视图中,添加以下代码,调整名称为 DSL:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Shell;
namespace Company.EmbedInForm
{
  public partial class UserControl1 : UserControl
  {
    public UserControl1()
    {
      InitializeComponent();
    }
    
    private DiagramDocView docView;
    public UserControl1(DiagramDocView docView, Control content)
      : this()
    {
      this.docView = docView;
      panel1.Controls.Add(content);
    }
    private void button1_Click(object sender, EventArgs e)
    {
      ExampleModel modelRoot = this.docView.CurrentDiagram.ModelElement as ExampleModel;
      foreach (ExampleElement element in modelRoot.Elements)
      {
       listBox1.Items.Add(element.Name);
      }
    }
  }
  internal partial class EmbedInFormDocView
  {
    private ContainerControl container;
    /// <summary>
    /// Return a User Control instead of the DSL window. 
    /// The user control will contain the DSL window.
    /// </summary>
    public override System.Windows.Forms.IWin32Window Window
    {
      get
      {
        if (container == null)
        {
          // Put the normal DSL Window inside our control
          container = new UserControl1(this, (Control)base.Window);
        }
        return container;
      }
    }
  }
}

EditorFactory.cs

实例化 DocData 和 DocView。 它执行 Visual Studio 使用则打开一个标准接口,在 DSL 包启动时。 它在 Package.cs 的 ProvideEditorFactory 属性引用

GeneratedVSCT.vsct

找到标准菜单命令菜单,如关系图上下文菜单, 编辑 菜单,依此类推。 命令的代码在 CommandSet.cs。 可以重新定位或修改标准命令,因此,您可以添加拥有命令。 有关更多信息,请参见 编写用户命令和操作

ModelExplorer.cs

定义 DSL 模型资源管理器。 这是用户在关系图查看模型的树视图。

例如,您可以重写 InsertTreeView() 更改元素出现在模型资源管理器的顺序。

如果希望在模型资源管理器中选择保持与关系图选择同步,可使用以下代码:

protected override void OnSelectionChanged(global::System.EventArgs e)
{
base.OnSelectionChanged(e);
// get the selected element
DslModeling::ModelElement selectedElement = 
this.PrimarySelection as DslModeling::ModelElement;
// Select in the model explorer
SelectInModelExplorer<YOURLANGUAGEExplorerToolWindow>(selectedElement);
}
private void SelectInModelExplorer<T>(DslModeling::ModelElement modelElement)
where T : DslShell.ModelExplorerToolWindow
{
DslShell::ModelingPackage package = 
this.GetService(typeof(VSShell.Package)) as DslShell::ModelingPackage;
if (package != null)
{
// find the model explorer window
T explorerWindow = package.GetToolWindow(typeof(T), true) as T;
if (explorerWindow != null)
{
// get the tree container
DslShell.ModelExplorerTreeContainer treeContainer = 
explorerWindow.TreeContainer;
// find the tree node
DslShell.ExplorerTreeNode treeNode = 
treeContainer.FindNodeForElement(modelElement);
// select the node
explorerWindow.TreeContainer.ObjectModelBrowser.SelectedNode = treeNode;
}
}
}

ModelExplorerToolWindow.cs

定义模型资源管理器中显示的窗口。 处理项目的选择在 macro 资源管理器。

Package.cs

此文件定义 DSL 如何集成 Visual Studio。 在包的属性分类为处理程序的 DSL 文件的文件扩展名,定义其工具箱注册,并定义如何打开一个新窗口。 ,当第一个 DSL 加载到 Visual Studio 实例, Initialize() 方法调用一次。

Source.extension.vsixmanifest

若要自定义此文件,请编辑 .tt 文件。

警告说明警告
如果编辑 .tt 文件包含资源 (如图标或图形,请确保该资源在编译 VSIX 中。在解决方案资源管理器中,选择文件并确保 包含在 VSIX 属性是 True。

此文件控件 DSL 如何打包到一个 Visual Studio 集成扩展 (vsix)。 有关更多信息,请参见 部署域特定语言解决方案

请参见

概念

如何定义域特定语言

了解模型、类和关系

自定义和扩展域特定语言

其他资源

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