逐步解說:將主機連線至產生的指示詞處理器
您可以撰寫處理文字範本的主機。 基本自訂主應用程式示範於逐步解說:建立自訂文字範本主機。 您可以擴充該主機以新增函式,例如產生多個輸出檔案。
在本逐步解說中,您會擴充自訂主應用程式,使其支援呼叫指示詞處理器的文字範本。 當您定義特定領域語言時,它會為領域模型產生指示詞處理器。 指示詞處理器可讓使用者更輕鬆地撰寫可存取模型的範本,減少在範本中撰寫組件和匯入指示詞的需求。
注意
本逐步解說是以逐步解說:建立自訂文字範本主機為基礎所建置。 請先執行該逐步解說。
本逐步解說包含下列工作:
使用特定領域語言工具來產生以領域模型為基礎的指示詞處理器。
將自訂文字範本主機連線到產生的指示詞處理器。
使用產生的指示詞處理器測試自訂主應用程式。
必要條件
若要定義 DSL,您必須已安裝下列元件:
元件 | 連結 |
---|---|
Visual Studio | http://go.microsoft.com/fwlink/?LinkId=185579 |
Visual Studio SDK | http://go.microsoft.com/fwlink/?LinkId=185580 |
Visual Studio Visualization and Modeling SDK |
注意
文字範本轉換元件會作為 Visual Studio 延伸模組開發工作負載的一部分自動安裝。 您也可以從 Visual Studio 安裝程式的 [個別元件] 索引標籤加以安裝,其位於 [SDK、程式庫和架構] 底下。 從 [個別元件] 索引標籤安裝 Modeling SDK 元件。
此外,您必須在逐步解說:建立自訂文字模板主機中建立自訂文字範本轉換。
使用特定領域語言工具來產生指示詞處理器
在本逐步解說中,您會使用特定領域語言設計工具精靈來建立解決方案 DSLMinimalTest 的特定領域語言。
建立具有下列特性的特定領域語言解決方案:
名稱:DSLMinimalTest
解決方案範本:最低語言
副檔名:min
公司名稱:Fabrikam
如需建立特定領域語言解決方案的詳細資訊,請參閱如何:建立特定領域語言解決方案。
在 [建置] 功能表上,按一下 [建置方案]。
重要
此步驟會產生指示詞處理器,並在登錄中為其新增機碼。
在 [偵錯] 功能表上,按一下 [開始偵錯] 。
Visual Studio 的第二個執行個體隨即開啟。
在實驗性組建中,在 [方案總管] 中,按兩下 sample.min 檔案。
該檔案隨即在設計工具中開啟。 請注意,此模型有兩個元素 ExampleElement1 和 ExampleElement2,這兩個元素之間有連結。
關閉 Visual Studio 的第二個執行個體。
儲存解決方案,然後關閉特定領域語言設計工具。
將自訂文字範本主機連線到指示詞處理器
產生指示詞處理器之後,您可以連線指示詞處理器和您在逐步解說:建立自訂文字範本主機中建立的自訂文字範本主機。
開啟 CustomHost 解決方案。
在 [專案] 功能表上,按一下 [加入參考]。
[新增參考] 對話方塊隨即開啟,並且顯示 [.NET] 索引標籤。
新增下列參考:
Microsoft.VisualStudio.Modeling.Sdk.11.0
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.11.0
Microsoft.VisualStudio.TextTemplating.11.0
Microsoft.VisualStudio.TextTemplating.Interfaces.11.0
Microsoft.VisualStudio.TextTemplating.Modeling.11.0
Microsoft.VisualStudio.TextTemplating.VSHost.11.0
在 Program.cs 或 Module1.vb 頂端,新增下列程式碼:
找出
StandardAssemblyReferences
屬性的程式碼,並將其取代為以下程式碼:注意
在此步驟中,您會將參考新增至主機支援的已產生指示詞處理器所需的組件。
//the host can provide standard assembly references //the engine will use these references when compiling and //executing the generated transformation class //-------------------------------------------------------------- public IList<string> StandardAssemblyReferences { get { return new string[] { //if this host searches standard paths and the GAC //we can specify the assembly name like this: //"System" //since this host only resolves assemblies from the //fully qualified path and name of the assembly //this is a quick way to get the code to give us the //fully qualified path and name of the System assembly //--------------------------------------------------------- typeof(System.Uri).Assembly.Location, typeof(System.Uri).Assembly.Location, typeof(Microsoft.VisualStudio.Modeling.ModelElement).Assembly.Location, typeof(Microsoft.VisualStudio.Modeling.Diagrams.BinaryLinkShape).Assembly.Location, typeof(Microsoft.VisualStudio.TextTemplating.VSHost.ITextTemplating).Assembly.Location, typeof(Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation).Assembly.Location }; } }
找出
ResolveDirectiveProcessor
函式的程式碼,並將其取代為以下程式碼:重要
此程式碼包含您要連線的已產生指示詞處理器名稱的硬式編碼參考。 您可以輕鬆地讓這個操作更為通用,在該情況下,它會尋找登錄中列出的所有指示詞處理器,並嘗試尋找相符項目。 在該情況下,主機會使用任何產生的指示詞處理器。
//the engine calls this method based on the directives the user has //specified it in the text template //this method can be called 0, 1, or more times //--------------------------------------------------------------------- public Type ResolveDirectiveProcessor(string processorName) { //check the processor name, and if it is the name of the processor the //host wants to support, return the type of the processor //--------------------------------------------------------------------- if (string.Compare(processorName, "DSLMinimalTestDirectiveProcessor", StringComparison.InvariantCultureIgnoreCase) == 0) { try { string keyName = @"Software\Microsoft\VisualStudio\10.0Exp_Config\TextTemplating\DirectiveProcessors\DSLMinimalTestDirectiveProcessor"; using (RegistryKey specificKey = Registry.CurrentUser.OpenSubKey(keyName)) { if (specificKey != null) { List<string> names = new List<String>(specificKey.GetValueNames()); string classValue = specificKey.GetValue("Class") as string; if (!string.IsNullOrEmpty(classValue)) { string loadValue = string.Empty; System.Reflection.Assembly processorAssembly = null; if (names.Contains("Assembly")) { loadValue = specificKey.GetValue("Assembly") as string; if (!string.IsNullOrEmpty(loadValue)) { //the assembly must be installed in the GAC processorAssembly = System.Reflection.Assembly.Load(loadValue); } } else if (names.Contains("CodeBase")) { loadValue = specificKey.GetValue("CodeBase") as string; if (!string.IsNullOrEmpty(loadValue)) { //loading local assembly processorAssembly = System.Reflection.Assembly.LoadFrom(loadValue); } } if (processorAssembly == null) { throw new Exception("Directive Processor not found"); } Type processorType = processorAssembly.GetType(classValue); if (processorType == null) { throw new Exception("Directive Processor not found"); } return processorType; } } } } catch (Exception e) { //if the directive processor can not be found, throw an error throw new Exception("Directive Processor not found"); } } //if the directive processor is not one this host wants to support throw new Exception("Directive Processor not supported"); }
按一下 [ 檔案 ] 功能表上的 [ 全部儲存]。
在 [建置] 功能表上,按一下 [建置方案]。
使用指示詞處理器測試自訂主應用程式
若要測試自訂文字範本主機,您必須先撰寫可呼叫已產生指示詞處理器的文字範本。 然後,您要執行自訂主應用程式、將文字範本的名稱傳遞給它,並確認指示詞已正確處理。
建立文字範本以測試自訂主應用程式
建立文字檔,並將它命名為
TestTemplateWithDP.tt
。 您可以使用任何文字編輯器 (例如 [記事本]) 來建立檔案。將下列程式碼加入至此文字檔中:
注意
文字範本的程式設計語言與自訂主應用程式的語言不一定要相符。
Text Template Host Test <#@ template debug="true" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" #> <# //this is the call to the examplemodel directive in the generated directive processor #> <#@ DSLMinimalTest processor="DSLMinimalTestDirectiveProcessor" requires="fileName='<Your Path>\Sample.min'" provides="ExampleModel=ExampleModel" #> <# //uncomment this line to test that the host allows the engine to set the extension #> <# //@ output extension=".htm" #> <# //uncomment this line if you want to see the generated transformation class #> <# //System.Diagnostics.Debugger.Break(); #> <# //this code uses the results of the examplemodel directive #> <# foreach ( ExampleElement box in this.ExampleModel.Elements ) { WriteLine("Box: {0}", box.Name); foreach (ExampleElement linkedTo in box.Targets) { WriteLine("Linked to: {0}", linkedTo.Name); } foreach (ExampleElement linkedFrom in box.Sources) { WriteLine("Linked from: {0}", linkedFrom.Name); } WriteLine(""); } #>
在程式碼中,將 <YOUR PATH> 取代為您在第一個程序中所建立特定設計語言的 Sample.min 檔案路徑。
儲存並關閉檔案。
測試自訂主應用程式
開啟命令提示字元視窗。
輸入自訂主應用程式可執行檔的路徑,但是還不要按 ENTER。
例如,鍵入:
<YOUR PATH>CustomHost\bin\Debug\CustomHost.exe
注意
如果不要輸入位置路徑,您可以在 [Windows 檔案總管] 中瀏覽至 CustomHost.exe 檔,然後將該檔案拖曳到 [命令提示字元] 視窗中。
輸入空格。
輸入文字範本檔的路徑,然後按 ENTER。
例如,鍵入:
<YOUR PATH>TestTemplateWithDP.txt
注意
如果不要輸入位置路徑,您可以在 [Windows 檔案總管] 中瀏覽至 TestTemplateWithDP.txt 檔,然後將該檔案拖曳到 [命令提示字元] 視窗中。
自訂主應用程式隨即執行並開始文字範本轉換流程。
在 [Windows 檔案總管] 中,瀏覽至包含檔案 TestTemplateWithDP.txt 的資料夾。
該資料夾也會包含 TestTemplateWithDP1.txt 檔案。
開啟這個檔案來查看文字範本轉換的結果。
產生的文字輸出結果隨即出現,看起來應該如下所示:
Text Template Host Test Box: ExampleElement1 Linked to: ExampleElement2 Box: ExampleElement2 Linked from: ExampleElement1