共用方式為


了解 DSL 程式碼

定義域專屬語言 (DSL) 解決方案會產生一套 API,可用來讀取和更新在 DSL 的執行個體Visual Studio。 這個 API 定義從 DSL 定義產生的程式碼中。 本主題說明了產生的 API。

範例方案: 元件圖表

若要建立的解決方案,是大部分本主題中範例的來源,建立從 DSL 元件模型方案範本。 這是當您建立新的 DSL 方案時,就會出現標準範本。

注意事項注意事項

您可以使用 [架構] 功能表中的建立的 UML 元件圖表不相關的元件圖表 DSL 範本Visual Studio Ultimate。在新的專案 對話方塊方塊中,展開 其他專案的 Types\Extensibility ,然後按一下 [ 定義域專屬語言設計工具

按 f5 鍵與項實驗中,如果您不熟悉這個方案] 範本。 您建立的連接埠,連接埠] 工具拖曳到元件,而且可以連線的連接埠,請特別注意。

元件和相互連接的通訊埠

DSL 方案的結構

Dsl專案定義您的 DSL 的 API。 DslPackage專案定義如何與整合Visual Studio。 您也可以加入自己的專案,也可以包含從模型產生的程式碼。

Bb286947.collapse_all(zh-tw,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專案。

檔案名稱

描述

YourDslSchema.xsd

結構描述檔案,其中包含您的 DSL 的執行個體。 這個檔案會複製到編譯 (bin) 目錄。 當您安裝您的 DSL 時,您可以複製此檔案,以\Program Files\Microsoft Visual Studio 11.0\Xml\Schemas ,以便可以驗證模型檔。 如需詳細資訊,請參閱 部署網域指定的語言方案

如果您自訂序列化 DSL 總管] 中設定選項時,結構描述也會跟著變更。 不過,如果您撰寫自己的序列化程式碼時,這個檔案可能不會再代表實際的結構描述。 如需詳細資訊,請參閱 自訂檔案儲存體和 XML 序列化

ConnectionBuilders.cs

連接產生器是一個類別,會建立關聯性。 它是 [連接] 工具背後的程式碼。 這個檔案包含一對每個連接] 工具的類別。 他們的名稱衍生自 「 網域關聯性和連線 」 工具的名稱: 關係產生器 」,以及 ConnectorToolConnectAction。

(如果元件方案範例中,呼叫 ConnectionBuilder 的其中一個連接產生器,這是這麼巧,因為網域關聯性的名稱是連線)。

在建立關聯性關係Builder.Connect()方法。 預設版本驗證來源和目標模型項目是可以接受的關聯性會具現化。 例如:

CommentReferencesSubject(sourceAccepted, targetAccepted);

每一個產生器類別從集中的節點產生的連接產生器 DSL 總管] 中的區段。 一個Connect方法可以建立一或多個組的網域類別之間的關聯性。 每一對連結連接詞,可以產生器] 節點下找到 DSL 總管] 中所定義。

比方說,您可以針對各種 DSL 的範例中的關聯性的三種將加入一個連接產生器連結連線的指示詞。 這會讓使用者使用單一連線的工具。 具現化的關聯性的類型而定的使用者所選取的來源和目標項目類型。 若要新增連結連線的指示詞,以滑鼠右鍵按一下 DSL 總管] 中的產生器]。

若要撰寫自訂執行的程式碼建立特定類型的網域關聯性時,請選取適當連線的指示連接詞產生器] 節點下。 在 [屬性] 視窗中,設定會使用自訂連線。 重建方案,並再提供程式碼以更正產生的錯誤。

若要撰寫自訂執行程式碼,每當使用者使用此連接] 工具時,設定是自訂連線建立幫手的屬性。 您可以提供決定是否允許來源項目,來源的特定組合是否允許目標,以及哪些更新程式應該設定成在模型建立連線時的程式碼。 比方說,您可能會在圖表中建立一個迴圈時,才會允許連線。 而非單一的關聯性連結,您可以執行個體化幾個來源和目標之間的 inter-related 項目更複雜的模式。

Connectors.cs

包含連接器,也就是圖表項目,通常表示參考的關聯性類別。 DSL 定義中的一個連接器可產生每個類別。 每個連接器類別衍生自BinaryLinkShape

若要讓在執行階段的色彩和一些其他的樣式功能變數,以滑鼠右鍵按一下圖表上的 DSL 定義類別,並指向加入公開

若要使執行階段的其他樣式功能變數,請參閱例如TextFieldShapeElement

Diagram.cs

包含定義圖表的類別。 它衍生自Diagram

若要讓在執行階段的色彩和一些其他的樣式功能變數,以滑鼠右鍵按一下圖表上的 DSL 定義類別,並指向加入公開

此外,這個檔案包含FixupDiagram規則,新的項目加入至模型時,會回應。 此規則會新增一個圖案,並的圖形連結至的模型項目。

DirectiveProcessor.cs

這個指示詞處理器可以幫助您撰寫文字範本讀取您的 DSL 的執行個體的使用者。 指示詞處理器載入您的 DSL 的組件 (Dll),並有效地插入using陳述式中的命名空間。 這樣的程式碼中的文字使用的範本類別和您已經定義好您的 DSL 的關聯性。

如需詳細資訊,請參閱 從網域指定的語言產生程式碼建立自訂 T4 文字範本指示詞處理器

DomainClasses.cs

類別實作之網域已定義,包括抽象類別和模型的根類別。 它們衍生自ModelElement

每個網域類別包含:

  • 屬性定義,每個網域內容的巢狀處理常式類別。 您可以覆寫 OnValueChanging() 和 OnValueChanged()。 如需詳細資訊,請參閱 網域屬性值變更處理常式

    在範例 DSL、 Comment類別包含某個屬性, Text和處理常式類別TextPropertyHandler。

  • 這個網域類別所參與的關聯性的存取子屬性。 (有為角色屬性沒有巢狀的類別)。

    在範例 DSL、 Comment類別有存取它的父模型透過內嵌的關聯性的存取子ComponentModelHasComments。

  • 建構函式。 如果您想要覆寫這些,設定有自訂建構函式網域類別上。

  • 項目群組原型 (EGP) 的處理常式方法。 這些是有必要,如果使用者可以合併 (加入) 到此類別的執行個體上的另一個項目。 通常使用者會從一個項目工具或另一個圖形,拖曳或貼上。

    此範例 DSL、 輸入連接埠或輸出連接埠可以合併到元件。 此外,元件註解可以合併到模型。

    EGP 處理常式方法,在元件類別可以讓元件接受連接埠,但不是註解。 註解和元件,但不是連接埠,就會接受 EGP 中的處理常式的根模型類別。

DomainModel.cs

表示網域模型類別。 它衍生自DomainModel

注意事項注意事項
這不是與模型的根類別相同。

複製和刪除結束定義其他項目應該要包含當您複製或刪除項目時。 您可以控制這個行為,藉由設定傳播複本傳播刪除處的角色的每個關聯性各端的內容。 如果您想要以動態方式判斷的值,您可以撰寫程式碼來覆寫終止類別的方法。 如需詳細資訊,請參閱HOW TO:程式複製和貼上行為 - 重新導向

DomainModelResx.resx

這包含這類的網域類別和屬性、 屬性名稱、 工具箱標籤、 標準錯誤訊息,以及其他可能向使用者顯示的字串描述的字串。 此外,它也會包含工具圖示和影像的圖形影像。

這個檔案所建置的組件中,繫結,並提供這些資源的預設值。 您可以藉由建立附屬組件包含當地語系化的版本的資源當地語系化您的 DSL。 DSL 安裝以符合當地語系化的資源文化特性時,將會使用該版本。 如需詳細資訊,請參閱 部署網域指定的語言方案

DomainRelationships.cs

網域關聯性類別的執行個體都擁有每個模型中的兩個元素之間的連結。 所有關聯性類別都衍生自lElementLink,其依序衍生自ModelElement。 因為它是 ModelElement,關聯性的執行個體可以有屬性,且可以是來源或目標關聯性。

HelpKeywordHelper.cs

提供當使用者按下 F1 時所使用的函式。

MultiplicityValidation.cs

在 [關聯角色,您可以在此指定的重數為 1..1 或 1..*,使用者應該會收到警告是必要的關聯性至少一個執行個體。 此檔案提供驗證限制條件,實作那些警告。 [1..1] 連結,以內嵌的父代不會加以驗證。

若要執行這些條件約束,您必須設定其中一個使用... 中的選項 Editor\Validation DSL 總管] 中的節點。 如需詳細資訊,請參閱 網域指定的語言中的驗證

PropertiesGrid.cs

這個檔案包含程式碼,只有當您附加自訂型別描述項至定義域屬性。 如需詳細資訊,請參閱 自訂屬性視窗

SerializationHelper.cs

  • 一種驗證方法,以確保沒有兩個項目所參考的同一個 moniker。 如需詳細資訊,請參閱 自訂檔案儲存體和 XML 序列化

  • SerializationHelper 類別,提供共同使用的序列化類別的函式。

Serializer.cs

每個網域類別、 關聯性、 圖形、 連接器、 圖表中和模型的序列化程式類別。

許多這些類別的功能可以控制下的 DSL 總管] 中設定 Xml 序列化行為

Shapes.cs

用來在 DSL 定義每個 shape 類別的類別。 圖形衍生自NodeShape。 如需詳細資訊,請參閱 自訂檔案儲存體和 XML 序列化

若要覆寫這些產生的方法,並在部分類別方法,設定會產生雙衍生在 DSL 定義連接器。 若要取代您自己的程式碼的建構函式,請將有自訂建構函式

若要讓在執行階段的色彩和一些其他的樣式功能變數,以滑鼠右鍵按一下圖表上的 DSL 定義類別,並指向加入公開

若要使執行階段的其他樣式功能變數,請參閱例如TextFieldShapeElement

ToolboxHelper.cs

設定工具箱] 中,藉由安裝項目群組的原型,到項目的工具。 當使用者執行此工具與目標項目合併這些原型的複本。

您可以覆寫CreateElementPrototype()來定義建立數個物件的一群的工具箱項目。 例如,您可定義項目來代表具有子元件的物件。 變更後的程式碼,重設實驗性的執行個體的Visual Studio來清除工具箱快取。

在 DslPackage 專案中產生的檔案

DslPackage 涉入 DSL 模型,以Visual Studio殼層,管理視窗、 [工具箱] 中和功能表命令。 大部分的類別是雙重衍生,以便您可以覆寫任何方法。

檔案名稱

描述

CommandSet.cs

在圖表上的 [看得見的內容功能表指令。 您可以調整,或加入至這個集合。 這個檔案包含命令的程式碼。 功能表上的指令的位置取決於 Commands.vsct 檔案。 如需詳細資訊,請參閱 撰寫使用者命令和動作

Constants.cs

Guid。

DocData.cs

YourDslDocData管理載入和儲存模型檔案,並建立存放區執行個體。

比方說,如果您想要的檔案而不是資料庫中儲存您的 DSL 時,您可以覆寫Load和Save方法。

DocView.cs

YourDslDocView管理此圖表會出現的視窗。 比方說,您無法內嵌圖表內表單的視窗:

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 封裝啟動時開啟編輯器。 參考的ProvideEditorFactory Package.cs 中的屬性

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

定義用來顯示 [模型總管] 中的視窗。 在 [檔案總管] 中的項目會處理。

Package.cs

這個檔案會定義如何將 DSL 整合成Visual Studio。 封裝類別上的屬性會為您的檔案副檔名,定義其工具箱] 中,並定義如何開啟新視窗的檔案的處理常式註冊 DSL。 Initialize() 方法呼叫一次,第一個 DSL 載入時Visual Studio執行個體。

Source.extension.vsixmanifest

若要自訂這個檔案,請編輯.tt檔案。

注意事項警告
如果您編輯包含資源,例如圖示或影像的.tt 檔案時,請確定資源已包含在 VSIX 的組建。在 [方案總管] 中,選取檔案,請確定加入至 VSIX 屬性是True。

此檔案會控制如何 DSL 封裝成 Visual Studio 整合副檔名 (VSIX)。 如需詳細資訊,請參閱 部署網域指定的語言方案

請參閱

概念

如何定義網域指定的語言

了解模型、類別和關聯性

自訂及擴充網域指定的語言

其他資源

撰寫程式碼來自訂網域指定的語言