共用方式為


使用文字範本中的 Visual Studio ModelBus

如果您撰寫文字範本來讀取包含 Visual Studio ModelBus 參考的模型,您可以解析參考以存取目標模型。 在此情況下,您必須調整文字範本和參考的特定領域語言 (DSL):

  • 作為參考目標的 DSL 必須具有為了從文字範本中存取而設定的 ModelBus 配接器。 如果您也會從其他程式碼存取 DSL,除了標準 ModelBus 配接器之外,還需要重新設定的配接器。

    配接器管理員必須繼承自 VsTextTemplatingModelingAdapterManager,而且必須具有 [HostSpecific(HostName)] 屬性。

  • 範本必須繼承自 ModelBusEnabledTextTransformation

注意

如果您想要讀取不包含 ModelBus 參考的 DSL 模型,您可以使用 DSL 專案中產生的指示詞處理器。 如需詳細資訊,請參閱從文字範本存取模型

如需有關文字範本的詳細資訊,請參閱使用 T4 文字範本產生設計階段程式碼

建立可用於從文字範本中存取的模型匯流排配接器

若要解析文字模板中的 ModelBus 參考,目標 DSL 必須具有相容的配接器。 文字範本會在與 Visual Studio 文件編輯器不同的 AppDomain 中執行,因此配接器必須載入模型,而不是透過 DTE 存取模型。

  1. 如果目標 DSL 解決方案沒有 ModelBusAdapter 專案,請使用 Modelbus 擴充功能精靈來加以建立:

    1. 如果您未安裝 Visual Studio ModelBus 擴充功能,請下載並安裝此擴充功能。 如需詳細資訊,請參閱視覺效果和模型化 SDK

    2. 開啟 DSL 定義檔。 以滑鼠右鍵按一下設計介面,然後按一下 [啟用 ModelBus]

    3. 在對話方塊中,選取 [我要將這個 DSL 公開給 ModelBus]。 如果您要將這個 DSL 公開給其模型,又要讓這個 DSL 使用其他 DSL 的參考,您可以選取這兩個選項。

    4. 按一下 [確定]。 新專案 "ModelBusAdapter" 會隨即加入至 DSL 方案。

    5. 按一下 [轉換所有範本]

    6. 重建方案。

  2. 如果您想要從文字範本和其他程式碼 (例如命令) 中存取 DSL,請複製 ModelBusAdapter 專案:

    1. 在 Windows 檔案總管中,複製並貼上包含 ModelBusAdapter.csproj 的資料夾。

    2. 將專案檔重新命名 (例如,重新命名為 T4ModelBusAdapter.csproj)。

    3. 在 [方案總管] 中以滑鼠右鍵按一下方案節點,指向 [加入],然後按一下 [現有專案]。 找出新的配接器專案 T4ModelBusAdapter.csproj

    4. 在新專案的每個 *.tt 檔案中,變更命名空間。

    5. 在 [方案總管] 中,以滑鼠右鍵按一下新專案,然後按一下 [屬性]。 在屬性編輯器中,變更所產生組件的名稱和預設命名空間。

    6. 在 DslPackage 專案中,新增新配接器專案的參考,使其具有這兩個配接器的參考。

    7. 在 DslPackage\source.extension.tt 中,新增用於參考新配接器專案的行。

      <MefComponent>|T4ModelBusAdapter|</MefComponent>
      
    8. 轉換所有範本並重建解決方案。 不應發生建置錯誤。

  3. 在新配接器專案中,新增下列組件的參考:

    • Microsoft.VisualStudio.TextTemplating.11.0
    • Microsoft.VisualStudio.TextTemplating.Modeling.11.0
  4. 在 AdapterManager.tt 中:

    • 變更 AdapterManagerBase 的宣告,使其繼承自 VsTextTemplatingModelingAdapterManager

      public partial class <#= dslName =>AdapterManagerBase :

      Microsoft.VisualStudio.TextTemplating.Modeling.VsTextTemplatingModelingAdapterManager { ...

    • 在檔案結尾附近,取代 AdapterManager 類別之前的 HostSpecific 屬性。 移除下列程式碼:

      [DslIntegration::HostSpecific(DslIntegrationShell::VsModelingAdapterManager.HostName)]

      插入下列程式碼行:

      [Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]

      此屬性會篩選模型匯流排取用者搜尋配接器時可用的配接器集合。

  5. 轉換所有範本並重建解決方案。 不應發生建置錯誤。

撰寫可解析 ModelBus 參考的文字範本

一般而言,您會以從「來源」DSL 讀取和產生檔案的範本開始。 此範本會使用來源 DSL 專案中產生的指示詞,透過從文字範本存取模型中所述的方式讀取來源模型檔案。 不過,來源 DSL 包含「目標」DSL 的 ModelBus 參考。 因此,您想要讓範本程式碼解析參考並存取目標 DSL。 因此,您必須遵循下列步驟來調整範本:

  • 將範本的基底類別變更為 ModelBusEnabledTextTransformation

  • 在範本指示詞中包含 hostspecific="true"

  • 將組件參考新增至目標 DSL 及其配接器,並啟用 ModelBus。

  • 您不需要作為為目標 DSL 一部分產生的指示詞。

<#@ template debug="true" hostspecific="true" language="C#"
inherits="Microsoft.VisualStudio.TextTemplating.Modeling.ModelBusEnabledTextTransformation" #>
<#@ SourceDsl processor="SourceDslDirectiveProcessor" requires="fileName='Sample.source'" #>
<#@ output extension=".txt" #>
<#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.Integration.11.0" #>
<#@ assembly name = "Company.TargetDsl.Dsl.dll" #>
<#@ assembly name = "Company.TargetDsl.T4ModelBusAdapter.dll" #>
<#@ assembly name = "System.Core" #>
<#@ import namespace="Microsoft.VisualStudio.Modeling.Integration" #>
<#@ import namespace="Company.TargetDsl" #>
<#@ import namespace="Company.TargetDsl.T4ModelBusAdapters" #>
<#@ import namespace="System.Linq" #>
<#
  SourceModelRoot source = this.ModelRoot; // Usual access to source model.
  // In the source DSL Definition, the root element has a model reference:
  using (TargetAdapter adapter = this.ModelBus.CreateAdapter(source.ModelReference) as TargetAdapter)
  {if (adapter != null)
   {
      // Get the root of the target model:
      TargetRoot target = adapter.ModelRoot;
    // The source DSL Definition has a class "SourceElement" embedded under the root.
    // (Let's assume they're all in the same model file):
    foreach (SourceElement sourceElement in source.Elements)
    {
      // In the source DSL Definition, each SourceElement has an MBR property:
      ModelBusReference elementReference = sourceElement.ReferenceToTarget;
      // Resolve the target model element:
      TargetElement element = adapter.ResolveElementReference<TargetElement>(elementReference);
#>
     The source <#= sourceElement.Name #> is linked to: <#= element.Name #> in target model: <#= target.Name #>.
<#
    }
  }}
  // Other useful code: this.Host.ResolvePath(filename) gets an absolute filename
  // from a path that is relative to the text template.
#>

執行此文字範本時,SourceDsl 指示詞會載入 Sample.source 檔案。 範本可以從 this.ModelRoot 開始存取該模型的元素。 程式碼可以使用該 DSL 的領域類別和屬性。

此外,範本也可以解析 ModelBus 參考。 如果參考指向目標模型,組件指示詞可讓程式碼使用該模型 DSL 的領域類別和屬性。

  • 如果您不使用 DSL 專案所產生的指示詞,也應該包含下列專案。

    <#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.11.0" #>
    <#@ assembly name = "Microsoft.VisualStudio.TextTemplating.Modeling.11.0" #>
    
  • 使用 this.ModelBus 來取得 ModelBus 的存取權。

逐步解說:測試使用 ModelBus 的文字範本

在這個逐步解說中,您將會依照下列步驟進行:

  1. 建構兩個 DSL。 其中一個 DSL (取用者) 有一個 ModelBusReference 屬性,可參考另一個 DSL (提供者)。

  2. 在提供者中建立兩個 ModelBus 配接器:一個供文字範本存取,另一個用於一般程式碼。

  3. 在單一實驗專案中建立 DSL 的執行個體模型。

  4. 將某個模型中的領域屬性設定為指向另一個模型。

  5. 撰寫「按兩下」處理常式來開啟所指向的模型。

  6. 撰寫文字範本來載入第一個模型、追蹤另一個模型的參考,以及讀取另一個模型。

建構 ModelBus 可存取的 DSL

  1. 建立新的 DSL 解決方案。 在此範例中,選取 [工作流程] 解決方案範本。 將語言名稱設定為 MBProvider,並將副檔名設定為 ".provide"。

  2. 在 DSL 定義圖表中,以滑鼠右鍵按一下不在頂端附近的圖表空白部分,然後按一下 [啟用 Modelbus]

    如果您沒有看到 [啟用 Modelbus],請下載並安裝 VMSDK ModelBus 擴充功能。

  3. 在 [啟用 Modelbus] 對話方塊中,選取 [向 ModelBus 公開此 DSL],然後按一下 [確定]

    新專案 ModelBusAdapter 會加入至解決方案。

您現在有可讓文字範本透過 ModelBus 存取的 DSL。 命令、事件處理常式或規則的程式碼中可解析參考,這些參考全部都會在模型檔案編輯器的 AppDomain 中運作。 不過,文字範本會在個別的 AppDomain 中執行,而且在編輯模型時無法存取模型。 如果您想要從文字範本存取此 DSL 的 ModelBus 參考,則必須有個別的 ModelBusAdapter。

建立針對文字範本設定的 ModelBus 配接器

  1. 在檔案總管中,複製並貼上包含 ModelBusAdapter.csproj 的資料夾。

    將資料夾命名為 T4ModelBusAdapter

    將專案檔重新命名為 T4ModelBusAdapter.csproj

  2. 在方案總管中,將 T4ModelBusAdapter 新增至 MBProvider 解決方案。 以滑鼠右鍵按一下解決方案節點,指向 [新增],然後按一下 [現有專案]

  3. 以滑鼠右鍵按一下 T4ModelBusAdapter 專案節點,然後按一下 [屬性]。 在專案屬性視窗中,將 [組件名稱] 和 [預設命名空間] 變更為 Company.MBProvider.T4ModelBusAdapters

  4. 在 T4ModelBusAdapter 中的每個 *.tt 檔案中,將 "T4" 插入命名空間的最後一個部分,讓這一行類似下面這樣。

    namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>.T4ModelBusAdapters

  5. DslPackage 專案中,將專案參考新增至 T4ModelBusAdapter

  6. 在 DslPackage\source.extension.tt 中,將下列這一行新增至 <Content> 底下。

    <MefComponent>|T4ModelBusAdapter|</MefComponent>

  7. T4ModelBusAdapter 專案中,將參考新增至:Microsoft.VisualStudio.TextTemplating.Modeling.11.0

  8. 開啟 T4ModelBusAdapter\AdapterManager.tt:

    1. 將 AdapterManagerBase 的基底類別變更為 VsTextTemplatingModelingAdapterManager。 檔案的這個部分現在會類似下面這樣。

      namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>.T4ModelBusAdapters
      {
          /// <summary>
          /// Adapter manager base class (double derived pattern) for the <#= dslName #> Designer
          /// </summary>
          public partial class <#= dslName #>AdapterManagerBase
          : Microsoft.VisualStudio.TextTemplating.Modeling.VsTextTemplatingModelingAdapterManager
          {
      
    2. 在接近檔案結尾處,將下列額外的屬性插入到類別 AdapterManager 的前面。

      [Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]

      結果會類似下面這樣。

      /// <summary>
      /// ModelBus modeling adapter manager for a <#= dslName #>Adapter model adapter
      /// </summary>
      [Mef::Export(typeof(DslIntegration::ModelBusAdapterManager))]
      [Mef::ExportMetadata(DslIntegration::CompositionAttributes.AdapterIdKey,<#= dslName #>Adapter.AdapterId)]
      [DslIntegration::HostSpecific(DslIntegrationShell::VsModelingAdapterManager.HostName)]
      [Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]
      public partial class <#= dslName #>AdapterManager : <#= dslName #>AdapterManagerBase
      {
      }
      
  9. 在方案總管的標題列中,按一下 [轉換所有範本]

  10. 請按 F5

  11. 確認 DSL 正常運作。 在實驗專案中,開啟 Sample.provider。 關閉 Visual Studio 的實驗執行個體。

    此 DSL 的 ModelBus 參考現在可以在文字範本和一般程式碼中解析。

使用 ModelBus 參考領域屬性建構 DSL

  1. 使用最小語言解決方案範本來建立新的 DSL。 將語言命名為 MBConsumer,並將副檔名設定為 ".consume"。

  2. 在 DSL 專案中,新增 MBProvider DSL 組件的參考。 以滑鼠右鍵按一下 MBConsumer\Dsl\References,然後按一下 [新增參考]。 在 [瀏覽] 索引標籤中,找出 MBProvider\Dsl\bin\Debug\Company.MBProvider.Dsl.dll

    這可讓您建立使用其他 DSL 的程式碼。 如果您想要建立數個 DSL 的參考,請同時新增這些參考。

  3. 在 DSL 定義圖表中,以滑鼠右鍵按一下圖表,然後按一下 [啟用 ModelBus]。 在對話方塊中,選取 [啟用此 DSL 以取用 ModelBus]

  4. ExampleElement 類別中,新增領域屬性 MBR,然後在 [屬性] 視窗中,將其類型設定為 ModelBusReference

  5. 以滑鼠右鍵按一下圖表上的領域屬性,然後按一下 [編輯 ModelBusReference 特定屬性]。 在對話方塊中,選取模型元素

    將檔案對話方塊篩選設定為下列內容。

    Provider File|*.provide

    "|" 後面的 substring 是檔案選取對話方塊的篩選條件。 您可以使用 *.*,將其設定為允許任何檔案

    在 [模型元素類型] 清單中,輸入提供者 DSL 中一個或多個領域類別的名稱 (例如 Company.MBProvider.Task)。 其可以是抽象類別。 如果您將清單保留空白,則使用者可以設定任何元素的參考。

  6. 關閉對話方塊並轉換所有範本

    您已建立 DSL,其中包含另一個 DSL 中元素的參考。

建立解決方案中另一個檔案的 ModelBus 參考

  1. 在 MBConsumer 解決方案中,按 CTRL+F5。 Visual Studio 的實驗執行個體會在 MBConsumer\Debugging 專案中開啟。

  2. 將 Sample.provide 的複本新增至 MBConsumer\Debugging 專案。 這是必要的,因為 ModelBus 參考必須參考相同解決方案中的檔案。

    1. 以滑鼠右鍵按一下「偵錯」專案,並指向 [新增],然後按一下 [現有項目]

    2. 在 [新增項目] 對話方塊中,將篩選設定為 [所有檔案 (*.*)]

    3. 瀏覽至 MBProvider\Debugging\Sample.provide,然後按一下 [新增]

  3. 開啟 [Sample.consume]。

  4. 按一下一個範例圖形,然後在 [屬性] 視窗中,按一下 MBR 屬性中的 [...]。 在對話方塊中,按一下 [瀏覽],然後選取 Sample.provide。 在元素視窗中,展開「工作」類型,然後選取其中一個項目。

  5. 儲存檔案。 (請先不要關閉 Visual Studio 的實驗執行個體。)

    您已建立一個模型,其中包含另一個模型中元素的 ModelBus 參考。

解析文字範本中的 ModelBus 參考

  1. 在 Visual Studio 的實驗執行個體中,開啟範例文字範本檔案。 設定其內容,如下所示。

    <#@ template debug="true" hostspecific="true" language="C#"
    inherits="Microsoft.VisualStudio.TextTemplating.Modeling.ModelBusEnabledTextTransformation" #>
    <#@ MBConsumer processor="MBConsumerDirectiveProcessor" requires="fileName='Sample.consume'" #>
    <#@ output extension=".txt" #>
    <#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.Integration.11.0" #>
    <#@ assembly name = "Company.MBProvider.Dsl.dll" #>
    <#@ import namespace="Microsoft.VisualStudio.Modeling.Integration" #>
    <#@ import namespace="Company.MBProvider" #>
    <#
      // Property provided by the Consumer directive processor:
      ExampleModel consumerModel = this.ExampleModel;
      // Iterate through Consumer model, listing the elements:
      foreach (ExampleElement element in consumerModel.Elements)
      {
    #>
       <#= element.Name #>
    <#
        if (element.MBR != null)
      using (ModelBusAdapter adapter = this.ModelBus.CreateAdapter(element.MBR))
      {
              // If we allowed multiple types or DSLs in the MBR, discover type here.
        Task task = adapter.ResolveElementReference<Task>(element.MBR);
    #>
            <#= element.Name #> is linked to Task: <#= task==null ? "(null)" : task.Name #>
    <#
          }
      }
    #>
    
    

    請注意下列要點:

    • 必須設定 template 指示詞的 hostSpecificinherits 屬性。

    • 取用者模型可透過該 DSL 中產生的指示詞處理器,以一般方式進行存取。

    • 組件和匯入指示詞必須能夠存取 ModelBus 和提供者 DSL 的類型。

    • 如果您知道許多 MBR 都連結至相同的模型,最好只呼叫 CreateAdapter 一次。

  2. 儲存範本。 確認產生的文字檔類似下列內容。

    ExampleElement1
    ExampleElement2
         ExampleElement2 is linked to Task: Task2
    

解析軌跡處理常式中的 ModelBus 參考

  1. 如果 Visual Studio 的實驗執行個體正在執行,請將其關閉。

  2. 新增名為MBConsumer\Dsl\Custom.cs 的檔案,並將其內容設定為下列內容:

    namespace Company.MB2Consume
    {
      using Microsoft.VisualStudio.Modeling.Integration;
      using Company.MB3Provider;
    
      public partial class ExampleShape
      {
        public override void OnDoubleClick(Microsoft.VisualStudio.Modeling.Diagrams.DiagramPointEventArgs e)
        {
          base.OnDoubleClick(e);
          ExampleElement element = this.ModelElement as ExampleElement;
          if (element.MBR != null)
          {
            IModelBus modelbus = this.Store.GetService(typeof(SModelBus)) as IModelBus;
            using (ModelBusAdapter adapter = modelbus.CreateAdapter(element.MBR))
            {
              Task task = adapter.ResolveElementReference<Task>(element.MBR);
              // Open a window on this model:
              ModelBusView view = adapter.GetDefaultView();
              view.Show();
              view.SetSelection(element.MBR);
            }
          }
        }
      }
    }
    
  3. Ctrl+F5

  4. 在 Visual Studio 的實驗執行個體中開啟 Debugging\Sample.consume

  5. 在一個圖形上按兩下。

    如果您已在該元素上設定 MBR,則參考的模型會隨即開啟,並且已選取參考的元素。

注意

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