Exemplarische Vorgehensweise: Verbinden eines Hosts mit einem generierten Direktivenprozessor

Sie können Hosts schreiben, besitzen, der Textvorlagen verarbeitet.Erstellen eines einfachen benutzerdefinierten Host ist in Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten Textvorlagenhostsveranschaulicht.Sie können diesen Host erweitern, um Funktionen wie Generating mehrere Ausgabedateien hinzuzufügen.

In dieser exemplarischen Vorgehensweise erweitern Sie den benutzerdefinierten Host, damit er Textvorlagen unterstützt, die Direktivenprozessoren aufrufen.Wenn Sie eine domänenspezifische Sprache definieren, generiert sie einen Direktivenprozessor zum Domänenmodell.Der Direktivenprozessor vereinfacht, sodass Benutzer Vorlagen schreiben, die das Modell zugreifen und die Notwendigkeit reduziert Assembly- und von Import-Direktiven in den Vorlagen zu schreiben.

WarnhinweisVorsicht

Builds dieser exemplarischen Vorgehensweise auf Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten Textvorlagenhosts.Führen Sie diese exemplarische Vorgehensweise zunächst aus.

Diese exemplarische Vorgehensweise umfasst die folgenden Aufgaben:

  • Verwenden Domänenspezifische Sprachtools zum Erstellen eines Direktivenprozessors zu generieren, der auf ein Domänenmodell ist.

  • Verbinden eines benutzerdefinierten Textvorlagen Host an den generierten Direktivenprozessors.

  • Aktivieren des benutzerdefinierten Hosts mit dem generierten Direktivenprozessor getestet werden.

Vorbereitungsmaßnahmen

Um ein DSL zu definieren, müssen Sie die folgenden Komponenten installiert sein:

Visual Studio

https://go.microsoft.com/fwlink/?LinkId=185579

Visual Studio SDK

https://go.microsoft.com/fwlink/?LinkId=185580

Visual Studio-Visualisierung und Modellieren SDK

https://go.microsoft.com/fwlink/?LinkID=186128

Darüber hinaus müssen Sie die benutzerdefinierte Textvorlagentransformation verfügen, die in Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten Textvorlagenhostserstellt wird.

Verwenden von domänenspezifischen Sprachtoole zum Generieren eines Direktivenprozessors

In dieser exemplarischen Vorgehensweise verwenden Sie den domänenspezifischer Sprach-Designer-Assistenten, um eine domänenspezifische Sprache für die Projektmappe DSLMinimalTest zu erstellen.

Um domänenspezifische Sprachtoole verwenden, um einen Direktivenprozessor zu generieren, der auf ein Domänenmodell ist

  1. Erstellen Sie eine domänenspezifische Sprachen, die Projektmappe die folgenden Merkmale verfügt:

    • Name: DSLMinimalTest

    • Vorlage Lösungen: Minimale Sprache

    • Dateierweiterung: Minute

    • Firmenname: Fabrikam

    Weitere Informationen zum Erstellen einer domänenspezifischen Sprache finden Sie unter Gewusst wie: Erstellen einer domänenspezifischen SprachlösungProjektmappe.

  2. Klicken Sie im Menü Erstellen auf Projektmappe erstellen.

    Wichtiger HinweisWichtig

    In diesem Schritt wird den Direktivenprozessor und fügt es den Schlüssel in der Registrierung hinzufügen.

  3. Klicken Sie im Menü Debuggen auf Debuggen starten.

    Eine zweite Instanz von Visual Studio wird geöffnet.

  4. In der experimentellen Build in Projektmappen-Explorer, doppelklicken Sie auf die Datei sample.min.

    Die Datei wird im Designer geöffnet.Beachten Sie, dass das Modell zwei Elemente, ExampleElement1 und ExampleElement2 hat und ein Link zwischen ihnen.

  5. Schließen Sie die zweite Instanz von Visual Studio. 

  6. Speichern Sie die Projektmappe, und schließen Sie dann den domänenspezifischen Sprachdesigner.

Verbindung mit einem Text-Vorlagen-Hosts eines benutzerdefinierten Direktivenprozessors

Nachdem Sie den Direktivenprozessor generieren, schließen Sie den Direktivenprozessor und benutzerdefinierten Textvorlagenhost an, die Sie in Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten Textvorlagenhostserstellt haben.

So erstellen Sie einen benutzerdefinierten Textvorlagenhost an den generierten Direktivenprozessor her

  1. Öffnen Sie die CustomHost-Projektmappe.

  2. Klicken Sie im Menü Projekt auf Verweis hinzufügen.

    Das Verweis hinzufügen Dialogfeld wird geöffnet, und der angezeigten .NET Registerkarte.

  3. Fügen Sie die folgenden Verweise hinzu:

    • 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

  4. Klicken Sie am oberen Rand Program.cs oder Module1.vb fügen Sie die folgende Codezeile hinzu:

    using Microsoft.Win32;
    
    Imports Microsoft.Win32
    
  5. Suchen Sie den Code für die Eigenschaft StandardAssemblyReferences, und ersetzen Sie ihn durch folgenden Code:

    HinweisHinweis

    In diesem Schritt fügen Sie Verweise auf Assemblys hinzu, die von den generierten Direktivenprozessor erforderlich sind, den der Host unterstützt.

    //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
    
            };
        }
    }
    
  6. Suchen Sie den Code für die Funktion ResolveDirectiveProcessor, und ersetzen Sie ihn durch folgenden Code:

    Wichtiger HinweisWichtig

    Dieser Code enthält hartcodierte Verweise auf den Namen des generierten Direktivenprozessors, mit dem Sie eine Verbindung herstellen möchten.Sie können dies problemlos häufiger ausführen. In diesem Fall wird nach allen Direktivenprozessoren sucht in der Registrierung aufgeführt sind, und versucht, eine Übereinstimmung zu erzielen.In diesem Fall würde der Host bei jedem generierten Direktivenprozessor arbeiten.

    //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");
            }
    
  7. Klicken Sie im Menü Datei auf Alle speichern.

  8. Klicken Sie im Menü Erstellen auf Projektmappe erstellen.

Aktivieren des benutzerdefinierten Hosts mit dem Direktivenprozessor testen

Um den benutzerdefinierten Textvorlagenhost zu testen, müssen Sie zuerst eine Textvorlage schreiben, die den generierten Direktivenprozessor aufruft.Anschließend führen Sie den benutzerdefinierten Host aus, führen zu ihr den Namen der Textvorlage und überprüfen, ob die Direktive richtig verarbeitet werden.

So erstellen Sie eine Textvorlage zum Testen des benutzerdefinierten Hosts

  1. Erstellen Sie eine Textdatei, und nennen Sie sie TestTemplateWithDP.tt.Sie können einen beliebigen Text-Editor wie Editor verwenden, um die Datei zu erstellen.

  2. Fügen Sie folgenden Text in der Textdatei ein:

    HinweisHinweis

    Die Programmiersprache der Textvorlage muss nicht die des benutzerdefinierten Hosts entsprechen.

    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("");
        } 
    #>
    
    Text Template Host Test
    
    <#@ template debug="true" language="VB" 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 #>
    
    <#    
       For Each box as ExampleElement In Me.ExampleModel.Elements 
    
           WriteLine("Box: {0}", box.Name)
    
            For Each LinkedTo as ExampleElement In box.Targets
                WriteLine("Linked to: {0}", LinkedTo.Name)
            Next
    
            For Each LinkedFrom as ExampleElement In box.Sources
                WriteLine("Linked from: {0}", LinkedFrom.Name)
            Next
    
            WriteLine("")
    
       Next 
    #>
    
  3. Ersetzen Sie im Code für <YOUR PATH> den Pfad der Sample.min-Datei von der Entwurf bestimmte Sprache, die Sie im ersten Verfahren erstellt haben.

  4. Speichern und schließen Sie die Datei.

So testen Sie den benutzerdefinierten Host

  1. Öffnen Sie ein Eingabeaufforderungsfenster.

  2. Geben Sie den Pfad der ausführbaren Datei für den benutzerdefinierten Host ein, drücken Sie aber noch nicht die EINGABETASTE.

    Beispiel:

    <YOUR PATH>CustomHost\bin\Debug\CustomHost.exe

    HinweisHinweis

    Anstatt die Adresse einzugeben, können Sie die Datei in Windows ExplorerCustomHost.exe durchsuchen und ziehen die Datei dann in das Eingabeaufforderungsfenster.

  3. Geben Sie ein Leerzeichen ein.

  4. Geben Sie den Pfad der Textvorlagendatei ein, und drücken Sie dann die EINGABETASTE.

    Beispiel:

    <YOUR PATH>TestTemplateWithDP.txt

    HinweisHinweis

    Anstatt die Adresse einzugeben, können Sie die Datei TestTemplateWithDP.txt in Windows ExplorerDurchsuchen, und ziehen Sie die Datei dann in das Eingabeaufforderungsfenster.

    Die benutzerdefinierte Hostanwendung wird ausgeführt und startet den Textvorlagen-Transformationsprozess.

  5. In Windows Explorernavigieren Sie zu dem Ordner, der die Datei TestTemplateWithDP.txt.

    Der Ordner enthält auch die Datei TestTemplateWithDP1.txt.

  6. Öffnen Sie diese Datei, um die Ergebnisse der Textvorlagentransformation anzuzeigen.

    Die Ergebnisse der generierten Textausgabe wird angezeigt, und es sollte wie folgt aussehen:

    Text Template Host Test
    
    
    Box: ExampleElement1
    Linked to: ExampleElement2
    
    Box: ExampleElement2
    Linked from: ExampleElement1
    

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten Textvorlagenhosts