Share via


特定領域語言的使用者入門

本主題將從基本概念中說明如何定義和使用隨著 Modeling SDK for Visual Studio 建立的特定領域語言 (DSL)。

注意

當您安裝 Visual Studio 的特定功能時,系統會自動安裝文字範本轉換 SDK 和 Visual Studio Modeling SDK。 如需詳細資訊,請參閱此部落格文章 (英文)。

如果您不熟悉 DSL,建議您瀏覽以下網站上的 DSL 工具實驗室Visualization and Modeling SDK

特定領域語言的用途為何?

特定領域語言是一種標記法 (通常是圖形的形式),其專為特定用途而設計。 相較之下,UML 之類的語言是為一般用途而設計的。 在 DSL 中,您可以定義模型元素的類型及其關聯性,以及其在螢幕上呈現的方式。

當您設計了 DSL 後,您就可以將其散發為 Visual Studio 整合延伸模組 (VSIX) 封裝的一部分。 使用者會在 Visual Studio 中使用 DSL:

Family tree diagram, toolbox, and explorer

標記法只是 DSL 的一部分。 除了標記法,您的 VSIX 封裝還包含可供使用者套用的工具,可協助他們從其模型中編輯和產生材料。

DSL 的其中一個主要應用是產生程式碼、設定檔和其他組建成品。 特別是在將產生許多產品變體的大型專案和產品線中,從 DSL 產生許多變數層面,可大幅提升可靠性,並快速回應需求變更。

本概觀的其餘部分是逐步解說,將介紹在 Visual Studio 中建立和使用特定領域語言的基本作業。

必要條件

若要定義 DSL,您必須已安裝下列元件:

元件 連結
Visual Studio http://go.microsoft.com/fwlink/?LinkId=185579
Visual Studio SDK https://go.microsoft.com/fwlink/?linkid=2166172
Modeling SDK for Visual Studio

注意

文字範本轉換元件會作為 Visual Studio 延伸模組開發工作負載的一部分自動安裝。 您也可以從 Visual Studio 安裝程式的 [個別元件] 索引標籤加以安裝,其位於 [SDK、程式庫和架構] 底下。 從 [個別元件] 索引標籤安裝 [模型化 SDK] 元件。

建立 DSL 方案

若要建立新的特定領域語言,請使用 [特定領域語言] 專案範本建立新的 Visual Studio 方案。

  1. [檔案] 功能表上,指向 [開新檔案] ,然後按一下 [專案]

  2. 在 [專案類型] 底下,展開 [其他專案類型] 節點,然後按一下 [擴充性]

  3. 按一下 [特定領域語言設計工具]

    Create DSL dialog

  4. 在 [名稱] 方塊中,輸入 FamilyTree。 按一下 [確定]

    [特定領域語言精靈] 會隨即開啟並顯示範本 DSL 方案的清單。

    按一下每一個範本可查看說明,

    範本是實用的起點。 每一個範本都會提供完整的工作 DSL,您可以加以編輯以符合您的需求。 一般而言,您可以選擇與您想建立的內容最接近的範本。

  5. 在此逐步解說中,請選擇 [最小語言] 範本。

  6. 在適當的精靈頁面中輸入 DSL 的副檔名。 這是包含 DSL 將使用之執行個體的檔案的副檔名。

    • 請選擇未與您公司中任何應用程式相關聯的副檔名,或是未與您要安裝 DSL 之任何電腦中的任何應用程式相關聯的副檔名。 例如,docxhtm 是無法接受的副檔名。

    • 如果您已輸入的副檔名正用來做為 DSL,精靈將會警告您。 請考慮使用不同的副檔名。 您也可以重設 Visual Studio SDK Experimental 執行個體以清除舊的實驗設計工具。 在 Windows 開始功能表中,輸入重設 Visual Studio,然後執行與您的 Visual Studio 版本相符的重設 Microsoft Visual Studio 實驗性實例命令。

  7. 檢查其他頁面,然後按一下 [完成]

    包含兩個專案的方案會隨即產生。 專案的名稱為 Dsl 和 DslPackage。 名為 DslDefinition.dsl 的圖表檔案會隨即開啟。

    注意

    您在兩個專案的資料夾中看到的大部分程式碼都是從 DslDefinition.dsl 產生的。 基於這個理由,對 DSL 所做的大部分修改都會在此檔案中進行。

這時使用者介面類似以下圖片。

dsl designer

此方案定義網域指定的語言。 如需詳細資訊,請參閱特定領域語言工具使用者介面的概觀

DSL 方案的重要部分

請注意新方案的下列層面:

  • Dsl\DslDefinition.dsl 這是您在建立 DSL 方案時看到的檔案。 方案中幾乎所有程式碼都是從此檔案產生的,而您對 DSL 定義所做的大部分變更都會在這裡進行。 如需詳細資訊,請參閱使用 DSL 定義圖表

  • Dsl 專案 此專案包含用來定義特定領域語言的程式碼。

  • DslPackage 專案 此專案包含程式碼,可讓 DSL 的執行個體在 Visual Studio 中開啟和編輯。

執行 DSL

只要建立了 DSL 方案,您就可以立即執行該方案。 您可以在之後逐步修改 DSL 定義,並在每次變更之後再次執行方案。

若要使用 DSL 進行試驗

  1. 在 [方案總管] 工具列中,按一下 [轉換所有範本]。 這會從 DslDefinition.dsl 重新產生大部分的原始程式碼。

    注意

    每次變更 DslDefinition.dsl 時,您必須先按一下 [轉換所有範本],才能重建方案。 您可以自動化此步驟。 如需詳細資訊,請參閱如何自動化轉換所有範本

  2. F5,或在 [偵錯] 功能表上,按一下 [開始偵錯]

    DSL 會在 Visual Studio 的實驗性執行個體中建置並安裝。

    Visual Studio 的實驗性執行個體隨即啟動。 在註冊 Visual Studio 延伸模組以用於偵錯的註冊中,實驗性執行個體會從該註冊的個別樹狀子目錄中取得其設定。 Visual Studio 的一般執行個體無法存取在該處註冊的延伸模組。

  3. 在 Visual Studio 的實驗性執行個體中,從方案總管開啟名為 Test 的模型檔案。

    - 或 -

    以滑鼠右鍵按一下「偵錯」專案,並指向 [新增],然後按一下 [項目]。 在 [新增項目] 對話方塊中,選取 DSL 的檔案類型。

    模型檔案會以空白圖表開啟。

    工具箱會隨即開啟,並顯示適合圖表類型的工具。

  4. 使用工具在圖表上建立圖形和連接器。

    1. 若要建立圖形,請從範例圖形工具拖曳至圖表。

    2. 若要連接兩個圖形,請按一下 [範例連接器] 工具,按一下第一個圖形,然後按一下第二個圖形。

  5. 按一下圖形的標籤可進行變更。

您的實驗性 Visual Studio 會類似下列範例:

Domain specific language sample tree in Visual Studio

模型的內容

檔案 (DSL 執行個體) 的內容稱為模型。 此模型包含模型元素和元素之間的連結。 DSL 定義會指定模型中可存在的模型元素和連結類型。 例如,從最小語言範本建立的 DSL 中會有一種模型類型和一種連結類型。

DSL 定義可以指定模型在圖表上的顯示方式。 您可以從各種圖形和連接器樣式中進行選擇。 您可以指定讓某些圖形出現在其他圖形內。

編輯模型時,您可以在 [總管] 檢視中以樹狀形式檢視模型。 當您將圖形新增至圖表時,模型元素也會出現在總管中。 即使其中沒有圖表,您也可以使用總管。

如果您在 Visual Studio 偵錯執行個體中沒看到「總管」,請在 [檢視] 功能表上指向 [其他視窗],然後按一下<您的語言>總管

DSL 的 API

您的 DSL 會產生 API,讓您可以讀取和更新作為 DSL 執行個體的模型。 API 的其中一個應用是從模型產生文字檔。 如需詳細資訊,請參閱使用 T4 文字範本產生設計階段程式碼

在偵錯解決方案中,開啟副檔名為 ".tt" 的範本檔案。 這些範例會示範如何從模型產生文字,並讓您測試 DSL 的 API。 其中一個範例會以 Visual Basic 撰寫,另一個則是以 Visual C# 撰寫。

在每個範本檔案底下的是其產生的檔案。 展開 [方案總管] 中的範本檔案,然後開啟產生的檔案。

範本檔案包含簡短的程式碼區段,用於列出模型中的所有元素。

產生的檔案會包含結果。

變更模型檔案時,您會在重新產生檔案之後,在產生的檔案中看到相對應的變更。

若要在變更模型檔案之後重新產生文字檔

  1. 在 Visual Studio 的實驗性執行個體中,儲存模型檔案。

  2. 請確定每個 .tt 檔案中的檔案名稱參數指的是您用於實驗的模型檔案。 儲存 .tt 檔案。

  3. 在 [方案總管] 的工具列中,按一下 [轉換所有範本]

    - 或 -

    以滑鼠右鍵按一下您想要重新產生的範本,然後按一下 [執行自訂工具]

您可以將任意數目的文字範本檔案新增至專案。 每個範本都會產生一個結果檔案。

注意

當您變更 DSL 定義時,除非您更新範例文字範本程式碼,否則範例文字範本程式碼將無法運作。

如需詳細資訊,請參閱從特定領域語言產生程式碼撰寫程式碼以自訂特定領域語言

自訂 DSL

當您想要修改 DSL 定義時,請關閉實驗性執行個體,並更新主要 Visual Studio 執行個體中的定義。

注意

修改 DSL 定義之後,使用舊版本所建立的測試模型中可能會遺失資訊。 例如,偵錯解決方案包含名為 Sample 的檔案,其中包含一些圖形和連接器。 在您開始開發 DSL 定義之後,這些內容並不會顯示,而且當您儲存檔案時,這些內容將會遺失。

您可以對 DSL 進行各種不同的擴充。 下列範例會讓您對可能性有個概念。

在每次變更之後,儲存 DSL 定義,按一下 [方案總管] 中的 [轉換所有範本],然後按 F5 以實驗變更的 DSL。

重新命名類型和工具

重新命名現有的領域類別和關聯性。 例如,從透過最小語言範本建立的 Dsl 定義開始,您可以執行下列重新命名作業,讓 DSL 代表家譜。

重新命名領域類別、關聯性和工具

  1. 在 DslDefinition 圖表中,將 ExampleModel 重新命名為 FamilyTreeModel、將 ExampleElement 重新命名為 Person、將 Targets 重新命名為 Parents,並將 Sources 重新命名為 Children。 您可以按一下每個標籤來進行變更。

    DSL Definition diagram - family tree model

  2. 重新命名元素和連接器工具。

    1. 按一下 [方案總管] 底下的索引標籤來開啟 [DSL 總管] 視窗。 如果沒看到該視窗,請在 [檢視] 功能表上指向 [其他視窗],然後按一下 [DSL 總管]。 只有當 DSL 定義圖表是使用中視窗時,才會顯示 DSL 總管。

    2. 開啟 [屬性] 視窗並放置該視窗,讓您可以同時看到 DSL 檔案總管和屬性。

    3. 在 [DSL 總管] 中,依序展開 [編輯器]、[工具箱] 索引標籤、<您的 DSL> 和 [工具]

    4. 按一下 [ExampleElement]。 這是用來建立元素的工具箱項目。

    5. 在 [屬性] 視窗中,將 Name 屬性變更為 Person

      請注意,Caption 屬性也會變更。

    6. 同樣地,將 ExampleConnector 工具的名稱變更為 ParentLink。 改變 Caption 屬性,使其不是 Name 屬性的複本。 例如,輸入父連結

  3. 重建 DSL。

    1. 儲存 DSL 定義檔。

    2. 在 [方案總管] 的工具列中,按一下 [轉換所有範本]

    3. 按下 F5。 等到 Visual Studio 的實驗性執行個體出現為止。

  4. 在 Visual Studio 實驗性執行個體的偵錯解決方案中,開啟測試模型檔案。 將元素從工具箱拖曳到其中。 請注意,DSL 總管中的工具標題和類型名稱已變更。

  5. 儲存模型檔案。

  6. 開啟 .tt 檔案,並以新名稱取代存在的舊類型和屬性名稱。

  7. 請確定 .tt 檔案中指定的檔案名會指定您的測試模型。

  8. 儲存 .tt 檔案。 開啟產生的檔案,以查看在 .tt 檔案中執行程式碼的結果。 確認其正確無誤。

將領域屬性新增至類別

將屬性新增至領域類別,例如,用於表示個人 (Person) 的出生和死亡年份。

若要在圖表上顯示新的屬性,您必須將裝飾項目新增至顯示模型元素的圖形。 您也必須將屬性對應至裝飾項目。

若要新增屬性並使其顯示
  1. 新增屬性。

    1. 在 DSL 定義圖表中,以滑鼠右鍵按一下 Person 領域類別,指向 [新增],然後按一下 [領域屬性]

    2. 輸入新的屬性名稱清單,例如 BirthDeath。 在每個名稱之後按 Enter

  2. 新增裝飾項目,以顯示圖形中的屬性。

    1. 遵循從 Person 領域類別延伸至圖表另一端的灰色線條。 這是圖表元素對應。 這會將領域類別連結至圖形類別。

    2. 以滑鼠右鍵按一下此圖形類別,指向 [新增],然後按一下 [文字裝飾項目]

    3. 新增兩個裝飾項目,例如可命名為 BirthDecoratorDeathDecorator

    4. 選取每個新的裝飾項目,然後在 [屬性] 視窗中設定 [位置] 欄位。 這會決定圖形上將顯示定領域屬性值的位置。 例如,設定 InnerBottomLeftInnerBottomRight

      Compartment shape definition

  3. 將裝飾項目對應至屬性。

    1. 開啟 [DSL 詳細資料] 視窗。 其通常位於 [輸出] 視窗旁邊的索引標籤中。 如果沒看到該視窗,請在 [檢視] 功能表上指向 [其他視窗],然後按一下 [DSL 詳細資料]

    2. 在 DSL 定義圖表上,按一下將 Person 領域類別連接到圖形類別的線條。

    3. 在 [DSL 詳細資料] 的 [裝飾項目對應] 索引標籤上,按一下未對應裝飾項目上的核取方塊。 在 [顯示屬性] 中,選取您想要對應的領域屬性。 例如,將 BirthDecorator 對應至 Birth

  4. 儲存 DSL,按一下 [轉換所有範本],然後按 F5。

  5. 在範例模型圖表中,確認您現在可以按一下您選擇的位置,並在其中輸入值。 此外,當您選取 Person 圖形時,[屬性] 視窗會顯示新的屬性 Birth 和 Death。

  6. 在 .tt 檔案中,您可以新增程式碼以取得每個人的屬性。

    Family tree diagram, toolbox, and explorer

定義新類別

您可以將領域類別和關聯性新增至模型。 例如,您可以建立新的類別來代表城鎮,並建立新關聯性來代表住在城鎮的某個人。

若要讓模型圖表上的不同類型有所差異,您可以將領域類別對應至不同類型的圖形,或對應至使用不同幾何和色彩的圖形。

若要新增和顯示新的領域類別
  1. 新增領域類別,並將其設為模型根目錄的子系。

    1. 在 DSL 定義圖表中,按一下 [內嵌關係] 工具、按一下根類別 FamilyTreeModel,然後按一下圖表的空白處。

      新的領域類別會隨即出現,該類別會使用內嵌關係連接到 FamilyTreeModel。

      設定其名稱,例如 Town

      注意

      每個領域類別 (模型根類別除外) 都必須是至少一個內嵌關係的目標,或者必須繼承自身為內嵌目標的類別。 因此,使用內嵌關係工具建立領域類別通常很方便。

    2. 將領域屬性新增至新的類別,例如 Name

  2. 新增 Person 與 Town 之間的參考關聯性。

    1. 按一下 [參考關聯性] 工具、按一下 [Person],然後按一下 [Town]。

      DSL definition fragment: family tree root

      注意

      參考關聯性代表從模型樹狀結構某個部分到另一個部分的交互參考。

  3. 新增圖形來代表模型圖表上的城鎮。

    1. 幾何圖形從工具箱中拖曳至圖表,然後將其重新命名,例如 TownShape

    2. 在 [屬性] 視窗中,設定新圖形的 [外觀] 欄位,例如 [填滿色彩] 和 [幾何]。

    3. 新增裝飾項目以顯示該城鎮的名稱,並將其重新命名為 NameDecorator。 設定其 Position 屬性。

  4. 將 Town 領域類別對應至 TownShape。

    1. 按一下 [圖表元素對應] 工具、按一下 [鎮域] 領域類別,然後按一下 [TownShape] 圖形類別。

    2. 在 [DSL 詳細資料] 視窗 (已選取對應連接器) 的 [裝飾項目對應] 索引標籤中,檢查 NameDecorator 並將 [顯示屬性] 設定為 Name。

  5. 建立連接器以顯示 Person 與 Towns 之間的關聯性。

    1. 將連接器從工具箱拖曳至圖表。 將其重新命名並設定其外觀屬性。

    2. 使用 [圖表元素對應] 工具,將新的連接器連結到 Person 與 Town 之間的關聯性。

      Family Tree definition with added shape map

  6. 建立元素工具以建立新的 Town。

    1. 在 [DSL 總管] 中,依序展開 [編輯器] 和 [工具箱] 索引標籤。

    2. 以滑鼠右鍵按一下<您的 DSL>,然後按一下 [新增元素工具]

    3. 設定新工具的 Name 屬性,並將其 Class 屬性設定為 Town。

    4. 設定 Toolbox Icon 屬性。 按一下 [...],然後在 [檔案名稱] 欄位中選取圖示檔案。

  7. 建立連接器工具,以建立城鎮與人之間的連結。

    1. 以滑鼠右鍵按一下<您的 DSL>,然後按一下 [新增連接器工具]

    2. 設定新工具的 Name 屬性。

    3. ConnectionBuilder 屬性中,選取包含 Person-Town 關聯性名稱的建立器。

    4. 設定 Toolbox Icon

  8. 儲存 DSL 定義,按一下 [轉換所有範本],然後按 F5

  9. 在 Visual Studio 的實驗性執行個體中,開啟測試模型檔案。 使用新工具來建立城鎮,以及城鎮和人之間的連結。 請注意,您只能在正確的元素類型之間建立連結。

  10. 建立程式碼,以列出每個人居住的城鎮。 文字範本是其中一個可以執行這類程式碼的地方。 例如,您可以修改偵錯解決方案中現有的 Sample.tt 檔案,使其包含下列程式碼:

    <#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" debug="true" #>
    <#@ output extension=".txt" #>
    <#@ FamilyTree processor="FamilyTreeDirectiveProcessor" requires="fileName='Sample.ftree'" #>
    
    <#
      foreach (Person person in this.FamilyTreeModel.People)
      {
    #>
        <#= person.Name #><#if (person.Town != null) {#> of <#= person.Town.Name #> <#}#>
    
    <#
          foreach (Person child in person.Children)
      {
    #>
                <#= child.Name #>
    <#
      }
      }
    #>
    
    

    當您儲存 *.tt 檔案時,該檔案會建立包含人及其住所清單的附屬檔案。 如需詳細資訊,請參閱從特定領域語言產生程式碼

驗證和命令

您可以藉由新增驗證條件約束來進一步開發此 DSL。 這些條件約束是您可以定義的方法,用於確保模型處於正確的狀態。 例如,您可以定義條件約束來確保小孩的出生日期晚於其父母。 如果 DSL 使用者嘗試儲存破壞任何條件約束的模型,則驗證功能會顯示警告。 如需詳細資訊,請參閱特定領域語言中的驗證

您也可以定義使用者可叫用的功能表命令。 命令可以修改模型。 也可以與 Visual Studio 中的其他模型和外部資源互動。 如需詳細資訊,請參閱如何:修改標準功能表命令

部署 DSL

若要允許其他使用者使用特定領域語言,您可以散發 Visual Studio 延伸模組 (VSIX) 檔案。 這會在您建置 DSL 方案時建立。

在方案的 bin 資料夾中找出 .vsix 檔案。 將其複製到用來安裝該檔案的電腦。 在該電腦上,按兩下 VSIX 檔案。 DSL 可用於該電腦上所有的 Visual Studio 執行個體。

您可以使用相同的程序在自己的電腦上安裝 DSL,如此便不需要使用 Visual Studio 的實驗性執行個體。

如需詳細資訊,請參閱部署特定領域語言方案

移除舊的實驗性 DSL

如果您已建立不再需要的實驗性 DSL,您可以重設 Visual Studio 實驗性執行個體,將其從您的電腦中移除。

這會從您的電腦中移除所有實驗 DSL 和其他實驗性 Visual Studio 延伸模組。 這些是已在偵錯模式中執行的延伸模組。

此程序不會藉由執行 VSIX 檔案來移除已完整安裝的 DSL 或其他 Visual Studio 延伸模組。

若要重設 Visual Studio 實驗性執行個體

  1. 在 Windows 開始功能表中,輸入重設 Visual Studio,然後執行與您的 Visual Studio 版本相符的重設 Microsoft Visual Studio 實驗性實例命令。

  2. 重建任何實驗性 DSL 或其他您仍想要使用的實驗性 Visual Studio 延伸模組。