Freigeben über


Verwenden von Visual Studio-ModelBus in einer Textvorlage

Wenn Sie Textvorlagen schreiben, die ein Modell lesen, das Visual Studio ModelBus-Verweise enthält, möchten Sie vielleicht die Verweise auflösen, um auf die Zielmodelle zuzugreifen. In diesem Fall müssen Sie die Textvorlagen und die referenzierten domänenspezifischen Sprachen (DSLs) anpassen:

  • Die Ziel-DSL der Verweise muss über einen ModelBus-Adapter verfügen, der für den Zugriff über Textvorlagen konfiguriert ist. Wenn Sie auch mit anderem Code auf die DSL zugreifen, ist zusätzlich zum Standard-ModelBus-Adapter ein neu konfigurierter Adapter erforderlich.

    Der Adapter-Manager muss von VsTextTemplatingModelingAdapterManager erben und über das Attribut [HostSpecific(HostName)] verfügen.

  • Die Vorlage muss von ModelBusEnabledTextTransformation erben.

Hinweis

Wenn Sie DSL-Modelle lesen möchten, die keine ModelBus-Verweise enthalten, können Sie die Anweisungsprozessoren verwenden, die in Ihren DSL-Projekten generiert werden. Weitere Informationen finden Sie unter Zugreifen auf Modelle über Textvorlagen.

Weitere Informationen über Textvorlagen finden Sie unter Generieren von Code zur Entwurfszeit mithilfe von T4-Textvorlagen.

Erstellen eines Modellbus-Adapters für den Zugriff über Textvorlagen

Um einen ModelBus-Verweis in einer Textvorlage aufzulösen, braucht die Ziel-DSL einen kompatiblen Adapter. Textvorlagen werden in einer separaten AppDomain als die Visual Studio-Dokument-Editoren ausgeführt. Daher muss der Adapter das Modell laden, anstatt über DTE darauf zuzugreifen.

  1. Wenn die DSL-Ziellösung kein ModelBusAdapter-Projekt enthält, erstellen Sie eines mithilfe des Assistenten für die ModelBus-Erweiterung:

    1. Laden Sie die Visual Studio ModelBus-Erweiterung herunter, und installieren Sie sie, sofern dies noch nicht geschehen ist. Weitere Informationen finden Sie unter Visualisierungs- und Modellierungs-SDK.

    2. Öffnen Sie die DSL-Definitionsdatei. Klicken Sie mit der rechten Maustaste auf die Designoberfläche und klicken Sie dann auf ModelBus aktivieren.

    3. Wählen Sie im Dialogfeld Ich möchte diese DSL für ModelBus verfügbar machen aus. Sie können beide Optionen auswählen, wenn diese DSL Modelle verfügbar machen soll und Verweise auf andere DSLs nutzen soll.

    4. Klicken Sie auf OK. Der DSL-Projektmappe wird ein neues ModelBusAdapter-Projekt hinzugefügt.

    5. Klicken Sie auf Alle Vorlagen transformieren.

    6. Generieren Sie die Projektmappe neu.

  2. Wenn Sie auf die DSL sowohl über eine Textvorlage als auch über anderen Code (wie einem Befehl) zugreifen möchten, duplizieren Sie das ModelBusAdapter-Projekt:

    1. Kopieren Sie im Windows-Explorer den Ordner, der ModelBusAdapter.csproj enthält, und fügen Sie ihn ein.

    2. Benennen Sie die Projektdatei um (z. B. in T4ModelBusAdapter.csproj).

    3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten der Projektmappe, zeigen Sie auf Hinzufügen und klicken Sie anschließend auf Vorhandenes Projekt. Suchen Sie das neue Adapterprojekt T4ModelBusAdapter.csproj.

    4. Ändern Sie in jeder *.tt-Datei des neuen Projekts den Namespace.

    5. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das neue Projekt, und klicken Sie anschließend auf Eigenschaften. Ändern Sie im Eigenschaften-Editor die Namen der generierten Assembly und den Standardnamespace.

    6. Fügen Sie im DslPackage-Projekt einen Verweis auf das neue Adapterprojekt hinzu, damit es Verweise auf beide Adapter enthält.

    7. Fügen Sie in DslPackage\source.extension.tt eine Zeile hinzu, die auf Ihr neues Adapterprojekt verweist.

      <MefComponent>|T4ModelBusAdapter|</MefComponent>
      
    8. Alle Vorlagen transformieren und erstellen Sie die Projektmappe neu. Es sollten keine Buildfehler auftreten.

  3. Fügen Sie im neuen Adapterprojekt Verweise auf die folgenden Assemblys hinzu:

    • Microsoft.VisualStudio.TextTemplating.11.0
    • Microsoft.VisualStudio.TextTemplating.Modeling.11.0
  4. In AdapterManager.tt:

    • Ändern Sie die Deklaration von AdapterManagerBase, sodass sie von VsTextTemplatingModelingAdapterManager erbt.

      public partial class <#= dslName =>AdapterManagerBase :

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

    • Ersetzen Sie am Ende der Datei das HostSpecific-Attribut vor der AdapterManager-Klasse. Entfernen Sie die folgende Zeile:

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

      Fügen Sie die folgende Zeile ein:

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

      Dieses Attribut filtert den Satz von Adaptern, der verfügbar ist, wenn ein ModelBus-Consumer nach einem Adapter sucht.

  5. Alle Vorlagen transformieren und erstellen Sie die Projektmappe neu. Es sollten keine Buildfehler auftreten.

Schreiben einer Textvorlage, die ModelBus-Verweise auflösen kann

In der Regel beginnen Sie mit einer Vorlage, die Dateien aus einer „Quell“-DSL liest und generiert. Diese Vorlage verwendet die Direktive, die im Quell-DSL-Projekt generiert wird, um Quellmodelldateien auf die unter Zugreifen auf Modelle aus Textvorlagen beschriebene Weise zu lesen. Die Quell-DSL enthält jedoch ModelBus-Verweise auf eine „Ziel“-DSL. Sie sollten daher den Vorlagencode aktivieren, um die Verweise aufzulösen und auf die Ziel-DSL zuzugreifen. Daher müssen Sie die Vorlage anpassen, indem Sie die folgenden Schritte ausführen:

  • Ersetzen Sie die Basisklasse der Vorlage durch ModelBusEnabledTextTransformation.

  • Schließen Sie hostspecific="true" in die Vorlagendirektive ein.

  • Fügen Sie der Ziel-DSL sowie dem zugehörigen Adapter Assemblyverweise hinzu und aktivieren Sie ModelBus.

  • Die als Teil der Ziel-DSL generierte Anweisung benötigen Sie nicht.

<#@ 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.
#>

Wenn diese Textvorlage ausgeführt wird, lädt die SourceDsl-Anweisung die Datei Sample.source. Die Vorlage kann auf die Elemente dieses Modells ab this.ModelRoot zugreifen. Der Code kann die Domänenklassen und Eigenschaften dieser DSL verwenden.

Darüber hinaus kann die Vorlage ModelBus-Verweise auflösen. Wenn die Verweise auf das Zielmodell verweisen, lassen die Assemblyanweisungen zu, dass der Code die Domänenklassen und Eigenschaften der DSL dieses Modells verwendet.

  • Wenn Sie keine Anweisung verwenden, die von einem DSL-Projekt generiert wird, sollten Sie auch Folgendes einschließen.

    <#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.11.0" #>
    <#@ assembly name = "Microsoft.VisualStudio.TextTemplating.Modeling.11.0" #>
    
  • Verwenden Sie this.ModelBus, um Zugriff auf den ModelBus zu erhalten.

Exemplarische Vorgehensweise: Testen einer Textvorlage, die ModelBus verwendet

Im Verlauf dieser exemplarischen Vorgehensweise führen Sie die folgenden Schritte aus:

  1. Erstellen zweier DSLs. Eine DSL, der Consumer, verfügt über die Eigenschaft ModelBusReference, die auf die andere DSL, den Provider, verweisen kann.

  2. Erstellen Sie zwei ModelBus-Adapter im Provider: einen für den Zugriff durch Textvorlagen, der andere für gewöhnlichen Code.

  3. Erstellen Sie Instanzmodelle der DSLs in einem einzelnen experimentellen Projekt.

  4. Legen Sie eine Domäneneigenschaft in einem Modell so fest, dass sie auf das andere Modell verweist.

  5. Schreiben Sie einen Doppelklickhandler, der das Modell öffnet, auf das verwiesen wird.

  6. Schreiben Sie eine Textvorlage, die das erste Modell laden, dem Verweis auf das zweite Modell folgen und dieses lesen kann.

Erstellen einer DSL, auf die ModelBus zugreifen kann

  1. Erstellen Sie eine neue DSL-Projektmappe. Wählen Sie für dieses Beispiel die Projektmappenvorlage Aufgabenfluss aus. Legen Sie den Sprachnamen auf MBProvider und die Dateinamenerweiterung auf „.provide“ fest.

  2. Klicken Sie im DSL-Definitionsdiagramm mit der rechten Maustaste auf einen leeren Teil des Diagramms, der sich nicht in der Nähe des oberen Bereichs befindet, und klicken Sie dann auf ModelBus aktivieren.

    Wenn ModelBus aktivieren nicht angezeigt wird, laden Sie die VMSDK-ModelBus-Erweiterung herunter, und installieren Sie sie.

  3. Wählen Sie im Dialogfeld Modellbus aktivieren die Option Diese DSL für modelBus verfügbar machen aus, und klicken Sie dann auf OK.

    Der Projektmappe wird ein neues Projekt namens ModelBusAdapter hinzugefügt.

Sie verfügen jetzt über eine DSL, auf die Textvorlagen über ModelBus zugreifen können. Verweise darauf können im Code von Befehlen, Ereignishandlern oder Regeln aufgelöst werden, die alle in der AppDomain des Modelldatei-Editors ausgeführt werden. Textvorlagen werden jedoch in einer separaten AppDomain ausgeführt und können nicht auf ein Modell zugreifen, wenn es bearbeitet wird. Wenn Sie über eine Textvorlage auf ModelBus-Verweise auf diese DSL zugreifen möchten, benötigen Sie einen separaten ModelBusAdapter.

Erstellen eines ModelBus-Adapters, der für Textvorlagen konfiguriert ist

  1. Kopieren Sie im Datei-Explorer den Ordner, der ModelBusAdapter.csproj enthält, und fügen Sie ihn ein.

    Geben Sie dem Ordner den Namen T4ModelBusAdapter.

    Benennen Sie die Projektdatei in T4ModelBusAdapter.csproj um.

  2. Fügen Sie in Projektmappen-Explorer den T4ModelBusAdapter zu der MBProvider-Lösung hinzu. Klicken Sie mit der rechten Maustaste auf den Knoten der Projektmappe, zeigen Sie auf Hinzufügen und klicken Sie dann auf Vorhandenes Projekt.

  3. Klicken Sie mit der rechten Maustaste auf den Projektknoten von T4ModelBusAdapter und klicken Sie dann auf Eigenschaften. Ändern Sie im Projekteigenschaftenfenster den Assemblynamen und den Standardnamespace in Company.MBProvider.T4ModelBusAdapters.

  4. Fügen Sie in jeder *.tt-Datei in T4ModelBusAdapter „T4“ in den letzten Teil des Namespace ein, sodass die Zeile wie folgt aussieht.

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

  5. Fügen Sie im Projekt DslPackage einen Projektverweis auf T4ModelBusAdapter ein.

  6. Fügen Sie in DslPackage\source.extension.tt die folgende Zeile unter <Content> hinzu.

    <MefComponent>|T4ModelBusAdapter|</MefComponent>

  7. Fügen Sie im Projekt T4ModelBusAdapter einen Verweis auf Microsoft.VisualStudio.TextTemplating.Modeling.11.0 hinzu.

  8. Öffnen Sie T4ModelBusAdapter\AdapterManager.tt:

    1. Ändern Sie die Basisklasse von AdapterManagerBase in VsTextTemplatingModelingAdapterManager. Dieser Teil der Datei sieht nun in etwa so aus:

      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. Fügen Sie am Ende der Datei dieses zusätzliche Attribut vor der Klasse AdapterManager:

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

      Das Ergebnis sieht in etwa so aus:

      /// <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. Klicken Sie auf der Titelleiste des Projektmappen-Explorers auf Alle Vorlagen transformieren.

  10. Drücken Sie F5.

  11. Vergewissern Sie sich, dass die DSL funktioniert. Öffnen Sie Sample.provider im experimentellen Projekt. Schließen Sie die experimentelle Instanz von Visual Studio.

    ModelBus-Verweise auf diese DSL können jetzt in Textvorlagen und auch in normalem Code aufgelöst werden.

Erstellen einer DSL mit einer ModelBus-Verweis-Domäneneigenschaft

  1. Erstellen Sie eine neue DSL mithilfe der Projektmappenvorlage „Minimale Sprache“. Nennen Sie die Sprache MBConsumer und legen Sie die Dateinamenerweiterung auf „.consume“ fest.

  2. Fügen Sie im DSL-Projekt einen Verweis auf die DSL-Assembly „MBProvider“ hinzu. Klicken Sie mit der rechten Maustaste auf MBConsumer\Dsl\References und klicken Sie dann auf Verweis hinzufügen. Machen Sie MBProvider\Dsl\bin\Debug\Company.MBProvider.Dsl.dll auf der Registerkarte Durchsuchen ausfindig.

    Dadurch können Sie Code erstellen, der die andere DSL verwendet. Wenn Sie Verweise auf mehrere DSLs erstellen möchten, fügen Sie diese auch hinzu.

  3. Klicken Sie im DSL-Definitionsdiagramm mit der rechten Maustaste auf das Diagramm und klicken Sie dann auf ModelBus aktivieren. Wählen Sie im Dialogfeld Dieser DSL ermöglichen, den ModelBus zu nutzen.

  4. Fügen Sie in der ExampleElement-Klasse eine neue Domäneneigenschaft namens MBR hinzu und legen Sie im Eigenschaftenfenster ihren Typ auf ModelBusReference fest.

  5. Klicken Sie mit der rechten Maustaste auf die Domäneneigenschaft und klicken Sie dann auf Spezifische Eigenschaften für ModelBus-Verweise bearbeiten. Wählen Sie im Dialogfeld ein Modellelement aus.

    Stellen Sie den Dateidialogfilter wie folgt ein.

    Provider File|*.provide

    Der substring nach „|“ ist ein Filter für das Dateiauswahl-Dialogfeld. Sie können festlegen, dass alle Dateien zulässig sind, indem Sie *.* verwenden.

    Geben Sie in der Liste Modellelementtyp die Namen einer oder mehrerer Domänenklassen in der Anbieter-DSL ein (z. B. Company.MBProvider.Task). Diese können abstrakte Klassen sein. Wenn Sie die Liste leer lassen, kann der Benutzer den Verweis auf ein beliebiges Element festlegen.

  6. Schließen Sie das Dialogfeld und führen Sie Alle Vorlagen transformieren aus.

    Sie haben eine DSL erstellt, die Verweise auf Elemente in einer anderen DSL enthalten kann.

Erstellen eines ModelBus-Verweises auf eine andere Datei in der Projektmappe

  1. Drücken Sie in der Projektmappe „MBConsumer“ STRG+F5. Eine experimentelle Instanz von Visual Studio wird im Projekt MBConsumer\Debugging geöffnet.

  2. Fügen Sie dem Projekt MBConsumer\Debugging eine Kopie von Sample.provide hinzu. Dies ist erforderlich, da ein ModelBus-Verweis auf eine Datei in derselben Projektmappe verweisen muss.

    1. Klicken Sie mit der rechten Maustaste auf das Debuggingprojekt, zeigen Sie auf Hinzufügen, und klicken Sie dann auf Vorhandenes Element.

    2. Legen Sie im Dialogfeld Element hinzufügen den Filter auf Alle Dateien (*.*) fest.

    3. Navigieren Sie zu MBProvider\Debugging\Sample.provide und klicken Sie dann auf Hinzufügen.

  3. Öffnen Sie Sample.consume.

  4. Klicken Sie auf eine Beispielform, und klicken Sie im Eigenschaftenfenster auf [...] in der MBR-Eigenschaft. Klicken Sie im Dialogfeld auf Durchsuchen und wählen Sie Sample.provide aus. Erweitern Sie im Elementfenster den Typ Task, und wählen Sie eines der Elemente aus.

  5. Speichern Sie die Datei . (Schließen Sie die experimentelle Instanz von Visual Studio noch nicht.)

    Sie haben ein Modell erstellt, das einen ModelBus-Verweis auf ein Element in einem anderen Modell enthält.

Auflösen einer ModelBus-Referenz in einer Textvorlage

  1. Öffnen Sie in der experimentellen Instanz von Visual Studio eine Beispieltextvorlagendatei. Legen Sie den Inhalt wie folgt fest.

    <#@ 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 #>
    <#
          }
      }
    #>
    
    

    Beachten Sie die folgenden Punkte:

    • Die Attribute hostSpecific und inherits der template-Anweisung müssen festgelegt werden.

    • Auf das Consumermodell wird in der üblichen Weise über den Anweisungsprozessor zugegriffen, der in dieser DSL generiert wurde.

    • Die Assembly- und Importanweisungen müssen auf ModelBus und die Typen der Anbieter-DSL zugreifen können.

    • Wenn Sie wissen, dass viele MBRs mit demselben Modell verknüpft sind, empfiehlt es sich, CreateAdapter nur einmal aufzurufen.

  2. Speichern Sie die Vorlage. Stellen Sie sicher, dass die resultierende Textdatei ungefähr wie folgt aussieht.

    ExampleElement1
    ExampleElement2
         ExampleElement2 is linked to Task: Task2
    

Auflösen eines ModelBus-Verweises in einem Gestenhandler

  1. Schließen Sie die experimentelle Instanz von Visual Studio, falls sie ausgeführt wird.

  2. Fügen Sie eine Datei mit dem Namen MBConsumer\Dsl\Custom.cs hinzu und legen Sie deren Inhalt wie folgt fest:

    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. Drücken Sie STRG+F5.

  4. Öffnen Sie Debugging\Sample.consume in der experimentellen Instanz von Visual Studio.

  5. Doppelklicken Sie auf eine Form.

    Wenn Sie den MBR für dieses Element festgelegt haben, wird das Modell geöffnet, auf das verwiesen wird, und das Element, auf das verwiesen wird, ist ausgewählt.

Hinweis

Die Komponente Textvorlagentransformation wird automatisch als Teil der Workload Visual Studio-Erweiterungsentwicklung installiert. Sie können die Installation auch über die Registerkarte Einzelne Komponenten des Visual Studio-Installers unter der Kategorie SDKs, Bibliotheken und Frameworks durchführen. Installieren Sie die Komponente Modellierungs-SDK auf der Registerkarte Einzelne Komponenten.