Użycie programu Visual Studio ModelBus w szablonie tekstu

Jeśli piszesz szablony tekstowe, które odczytują model zawierający odwołania do modelu Visual Studio ModelBus, możesz chcieć rozpoznać odwołania w celu uzyskania dostępu do modeli docelowych. W takim przypadku należy dostosować szablony tekstowe i przywołyne języki specyficzne dla domeny (DSLS):

  • Język DSL, który jest obiektem docelowym odwołań, musi mieć kartę ModelBus skonfigurowaną do uzyskiwania dostępu z szablonów tekstowych. Jeśli uzyskujesz również dostęp do rozszerzenia DSL z innego kodu, ponownie skonfigurowana karta jest wymagana oprócz standardowej karty ModelBus.

    Menedżer kart musi dziedziczyć z elementu VsTextTemplatingModelingAdapterManager i musi mieć atrybut [HostSpecific(HostName)].

  • Szablon musi dziedziczyć z klasy ModelBusEnabledTextTransformation.

Uwaga

Jeśli chcesz odczytać modele DSL, które nie zawierają odwołań ModelBus, możesz użyć procesorów dyrektywy generowanych w projektach DSL. Aby uzyskać więcej informacji, zobacz Uzyskiwanie dostępu do modeli z szablonów tekstowych.

Aby uzyskać więcej informacji na temat szablonów tekstu, zobacz Projektowanie generowania kodu w czasie projektowania przy użyciu szablonów tekstowych T4.

Tworzenie adaptera magistrali modelu na potrzeby dostępu na podstawie szablonów tekstu

Aby rozwiązać problem z odwołaniem ModelBus w szablonie tekstowym, docelowa biblioteka DSL musi mieć zgodną kartę. Szablony tekstu są wykonywane w osobnym elemencie AppDomain z edytorów dokumentów programu Visual Studio, dlatego karta musi załadować model zamiast uzyskiwać do niego dostęp za pośrednictwem DTE.

  1. Jeśli docelowe rozwiązanie DSL nie ma projektu ModelBusAdapter , utwórz je za pomocą kreatora rozszerzenia Modelbus:

    1. Pobierz i zainstaluj rozszerzenie Visual Studio ModelBus, jeśli jeszcze tego nie zrobiono. Aby uzyskać więcej informacji, zobacz Wizualizacja i zestaw SDK modelowania.

    2. Otwórz plik definicji DSL. Kliknij prawym przyciskiem myszy powierzchnię projektową, a następnie kliknij pozycję Włącz modelbus.

    3. W oknie dialogowym wybierz pozycję Chcę uwidocznić ten język DSL dla modeluBus. Możesz wybrać obie opcje, jeśli chcesz, aby ten język DSL uwidocznił swoje modele i używać odwołań do innych list DSL.

    4. Kliknij przycisk OK. Nowy projekt "ModelBusAdapter" jest dodawany do rozwiązania DSL.

    5. Kliknij pozycję Przekształć wszystkie szablony.

    6. Skompiluj ponownie rozwiązanie.

  2. Jeśli chcesz uzyskać dostęp do biblioteki DSL zarówno z szablonu tekstowego, jak i z innego kodu, takiego jak polecenie, zduplikuj projekt ModelBusAdapter :

    1. W Eksploratorze Windows skopiuj i wklej folder zawierający plik ModelBusAdapter.csproj.

    2. Zmień nazwę pliku projektu (na przykład na T4ModelBusAdapter.csproj).

    3. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł rozwiązania, wskaż polecenie Dodaj, a następnie kliknij pozycję Istniejący projekt. Znajdź nowy projekt adaptera T4ModelBusAdapter.csproj.

    4. W każdym *.tt pliku nowego projektu zmień przestrzeń nazw.

    5. Kliknij prawym przyciskiem myszy nowy projekt w Eksplorator rozwiązań, a następnie kliknij polecenie Właściwości. W edytorze właściwości zmień nazwy wygenerowanego zestawu i domyślną przestrzeń nazw.

    6. W projekcie DslPackage dodaj odwołanie do nowego projektu adaptera, aby zawierało odwołania do obu kart.

    7. W obszarze DslPackage\source.extension.tt dodaj wiersz odwołujący się do nowego projektu adaptera.

      <MefComponent>|T4ModelBusAdapter|</MefComponent>
      
    8. Przekształć wszystkie szablony i ponownie skompiluj rozwiązanie. Nie powinny występować żadne błędy kompilacji.

  3. W nowym projekcie adaptera dodaj odwołania do następujących zestawów:

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

    • Zmień deklarację AdapterManagerBase, aby dziedziczyła z elementu VsTextTemplatingModelingAdapterManager.

      public partial class <#= dslName =>AdapterManagerBase :

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

    • Na końcu pliku zastąp atrybut HostSpecific przed klasą AdapterManager. Usuń następujący wiersz:

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

      Wstaw następujący wiersz:

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

      Ten atrybut filtruje zestaw kart, które są dostępne, gdy użytkownik modelubus wyszukuje kartę.

  5. Przekształć wszystkie szablony i ponownie skompiluj rozwiązanie. Nie powinny występować żadne błędy kompilacji.

Pisanie szablonu tekstowego, który może rozpoznawać odwołania modelBus

Zazwyczaj zaczynasz od szablonu, który odczytuje i generuje pliki z "źródłowej" biblioteki DSL. Ten szablon używa dyrektywy wygenerowanej w projekcie źródłowym DSL do odczytywania plików modelu źródłowego w sposób opisany w artykule Uzyskiwanie dostępu do modeli z szablonów tekstowych. Jednak źródłowa platforma DSL zawiera odwołania ModelBus do "docelowego" rozszerzenia DSL. W związku z tym chcesz umożliwić kodowi szablonu rozpoznawanie odwołań i uzyskiwanie dostępu do docelowego rozszerzenia DSL. W związku z tym należy dostosować szablon, wykonując następujące kroki:

  • Zmień klasę bazową szablonu na ModelBusEnabledTextTransformation.

  • Uwzględnij hostspecific="true" w dyrektywie szablonu.

  • Dodaj odwołania do zestawu do docelowego rozszerzenia DSL i jego karty oraz w celu włączenia modelu ModelBus.

  • Nie potrzebujesz dyrektywy, która jest generowana jako część docelowego rozszerzenia 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.
#>

Po wykonaniu SourceDsl tego szablonu tekstowego dyrektywa ładuje plik Sample.source. Szablon może uzyskiwać dostęp do elementów tego modelu, począwszy od this.ModelRoot. Kod może używać klas domen i właściwości tego rozszerzenia DSL.

Ponadto szablon może rozpoznawać odwołania ModeluBus. Gdzie odwołania wskazują model docelowy, dyrektywy zestawu pozwalają kodowi używać klas domen i właściwości rozszerzenia DSL tego modelu.

  • Jeśli nie używasz dyrektywy generowanej przez projekt DSL, należy również uwzględnić następujące elementy.

    <#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.11.0" #>
    <#@ assembly name = "Microsoft.VisualStudio.TextTemplating.Modeling.11.0" #>
    
  • Użyj this.ModelBus polecenia , aby uzyskać dostęp do modelu ModelBus.

Przewodnik: testowanie szablonu tekstowego korzystającego z modeluBus

W tym przewodniku wykonaj następujące kroki:

  1. Skonstruuj dwie listy DSL. Jeden DSL, Konsument, ma ModelBusReference właściwość, która może odwoływać się do drugiej DSL, Dostawca.

  2. Utwórz dwie karty ModelBus w dostawcy: jeden na potrzeby dostępu za pomocą szablonów tekstowych, drugi dla zwykłego kodu.

  3. Tworzenie modeli wystąpień listy DSL w jednym projekcie eksperymentalnym.

  4. Ustaw właściwość domeny w jednym modelu, aby wskazywała drugi model.

  5. Napisz procedurę obsługi dwukrotnego kliknięcia, która otwiera wskazywany model.

  6. Napisz szablon tekstowy, który może załadować pierwszy model, postępuj zgodnie z odwołaniem do innego modelu i odczytaj drugi model.

Konstruowanie rozszerzenia DSL dostępnego dla modeluBus

  1. Utwórz nowe rozwiązanie DSL. W tym przykładzie wybierz szablon rozwiązania Przepływ zadań. Ustaw nazwę języka na MBProvider i rozszerzenie nazwy pliku na ".provide".

  2. Na diagramie definicji DSL kliknij prawym przyciskiem myszy pustą część diagramu, która nie znajduje się w górnej części, a następnie kliknij pozycję Włącz modelbus.

    Jeśli nie widzisz opcji Włącz modelbus, pobierz i zainstaluj rozszerzenie VMSDK ModelBus.

  3. W oknie dialogowym Włącz modelbus wybierz pozycję Uwidaczniaj tę platformę DSL w modeluBus, a następnie kliknij przycisk OK.

    Nowy projekt, ModelBusAdapter, jest dodawany do rozwiązania.

Masz teraz rozszerzenie DSL, do którego można uzyskać dostęp za pomocą szablonów tekstowych za pośrednictwem modelu ModelBus. Odwołania do niego można rozpoznać w kodzie poleceń, procedur obsługi zdarzeń lub reguł, z których wszystkie działają w domenie AppDomain edytora plików modelu. Jednak szablony tekstowe są uruchamiane w osobnym elemencie AppDomain i nie mogą uzyskać dostępu do modelu podczas jego edytowania. Jeśli chcesz uzyskać dostęp do odwołań ModeluBus do tego rozszerzenia DSL z szablonu tekstowego, musisz mieć oddzielny modelBusAdapter.

Tworzenie adaptera ModelBus skonfigurowanego dla szablonów tekstowych

  1. W Eksplorator plików skopiuj i wklej folder zawierający plik ModelBusAdapter.csproj.

    Nadaj folderowi nazwę T4ModelBusAdapter.

    Zmień nazwę pliku projektu T4ModelBusAdapter.csproj.

  2. W Eksplorator rozwiązań dodaj element T4ModelBusAdapter do rozwiązania MBProvider. Kliknij prawym przyciskiem myszy węzeł rozwiązania, wskaż polecenie Dodaj, a następnie kliknij pozycję Istniejący projekt.

  3. Kliknij prawym przyciskiem myszy węzeł projektu T4ModelBusAdapter, a następnie kliknij polecenie Właściwości. W oknie właściwości projektu zmień nazwę zestawu i domyślną przestrzeń nazw na Company.MBProvider.T4ModelBusAdapters .

  4. W każdym pliku *.tt w T4ModelBusAdapter wstaw "T4" do ostatniej części przestrzeni nazw, tak aby wiersz przypominał następujący.

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

  5. W projekcie DslPackage dodaj odwołanie do projektu .T4ModelBusAdapter

  6. W pliku DslPackage\source.extension.tt dodaj następujący wiersz w obszarze <Content>.

    <MefComponent>|T4ModelBusAdapter|</MefComponent>

  7. W projekcie T4ModelBusAdapter dodaj odwołanie do: Microsoft.VisualStudio.TextTemplating.Modeling.11.0

  8. Otwórz plik T4ModelBusAdapter\AdapterManager.tt:

    1. Zmień klasę bazową AdapterManagerBase na VsTextTemplatingModelingAdapterManager. Ta część pliku jest teraz podobna do poniższej.

      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. Na końcu pliku wstaw następujący dodatkowy atrybut przed klasą AdapterManager.

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

      Wynik przypomina następujący.

      /// <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. Kliknij pozycję Przekształć wszystkie szablony na pasku tytułu Eksplorator rozwiązań.

  10. Naciśnij klawisz F5.

  11. Sprawdź, czy rozszerzenie DSL działa. W projekcie eksperymentalnym otwórz plik Sample.provider. Zamknij eksperymentalne wystąpienie programu Visual Studio.

    Odwołania modeluBus do tego języka DSL można teraz rozpoznać w szablonach tekstowych, a także w zwykłym kodzie.

Konstruowanie rozszerzenia DSL z właściwością domeny Odwołania modeluBus

  1. Utwórz nową bibliotekę DSL przy użyciu szablonu rozwiązania Minimalne języki. Nazwij język MBConsumer i ustaw rozszerzenie nazwy pliku na ".consume".

  2. W projekcie DSL dodaj odwołanie do zestawu DSL MBProvider. Kliknij prawym przyciskiem myszy MBConsumer\Dsl\References , a następnie kliknij polecenie Dodaj odwołanie. Na karcie Przeglądaj znajdź MBProvider\Dsl\bin\Debug\Company.MBProvider.Dsl.dll

    Dzięki temu można utworzyć kod, który używa innego rozszerzenia DSL. Jeśli chcesz utworzyć odwołania do kilku list DSL, dodaj je również.

  3. Na diagramie definicji DSL kliknij prawym przyciskiem myszy diagram, a następnie kliknij pozycję Włącz modelBus. W oknie dialogowym wybierz pozycję Włącz to rozszerzenie DSL, aby korzystać z modeluBus.

  4. W klasie ExampleElementdodaj nową właściwość MBRdomeny , a w okno Właściwości ustaw jej typ na ModelBusReference.

  5. Kliknij prawym przyciskiem myszy właściwość domeny na diagramie, a następnie kliknij polecenie Edytuj właściwości specyficzne dla modeluBusReference. W oknie dialogowym wybierz element modelu.

    Ustaw filtr okna dialogowego pliku na następujące.

    Provider File|*.provide

    Podciąg po "|" jest filtrem okna dialogowego wyboru pliku. Można ją ustawić tak, aby zezwalała na wszystkie pliki przy użyciu *.*

    Na liście Typ elementu modelu wprowadź nazwy co najmniej jednej klasy domeny w dostawcy DSL (na przykład Company.MBProvider.Task). Mogą to być klasy abstrakcyjne. Jeśli pozostawisz listę pustą, użytkownik może ustawić odwołanie do dowolnego elementu.

  6. Zamknij okno dialogowe i Przekształć wszystkie szablony.

    Utworzono rozszerzenie DSL, które może zawierać odwołania do elementów w innej architekturze DSL.

Tworzenie odwołania modeluBus do innego pliku w rozwiązaniu

  1. W rozwiązaniu MBConsumer naciśnij klawisze CTRL+F5. Eksperymentalne wystąpienie programu Visual Studio zostanie otwarte w projekcie MBConsumer\Debugowanie .

  2. Dodaj kopię pliku Sample.provide do projektu MBConsumer\Debug. Jest to konieczne, ponieważ odwołanie modelBus musi odwoływać się do pliku w tym samym rozwiązaniu.

    1. Kliknij prawym przyciskiem myszy projekt Debugowanie, wskaż polecenie Dodaj, a następnie kliknij pozycję Istniejący element.

    2. W oknie dialogowym Dodawanie elementu ustaw filtr na Wszystkie pliki (*.*).

    3. Przejdź do, MBProvider\Debugging\Sample.provide a następnie kliknij przycisk Dodaj.

  3. Otwórz Sample.consume.

  4. Kliknij jeden przykładowy kształt, a w okno Właściwości kliknij pozycję [...] we właściwości MBR. W oknie dialogowym kliknij przycisk Przeglądaj i wybierz pozycję Sample.provide. W oknie elementów rozwiń typ Zadanie i wybierz jeden z elementów.

  5. Zapisz plik. (Nie zamykaj jeszcze eksperymentalnego wystąpienia programu Visual Studio).

    Utworzono model zawierający odwołanie ModelBus do elementu w innym modelu.

Rozwiązywanie odwołania modeluBus w szablonie tekstowym

  1. W eksperymentalnym wystąpieniu programu Visual Studio otwórz przykładowy plik szablonu tekstowego. Ustaw jego zawartość w następujący sposób.

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

    Należy zauważyć następujące informacje:

    • Należy hostSpecific ustawić atrybuty template i inherits dyrektywy.

    • Dostęp do modelu konsumenta jest uzyskiwany w zwykły sposób za pośrednictwem procesora dyrektywy, który został wygenerowany w tym DSL.

    • Dyrektywy zestawu i importu muszą mieć dostęp do modelu ModelBus i typów dostawców DSL.

    • Jeśli wiesz, że wiele MBR jest połączonych z tym samym modelem, lepiej wywołać metodę CreateAdapter tylko raz.

  2. Zapisz szablon. Sprawdź, czy wynikowy plik tekstowy jest podobny do poniższego.

    ExampleElement1
    ExampleElement2
         ExampleElement2 is linked to Task: Task2
    

Rozwiązywanie odwołania modeluBus w procedurze obsługi gestów

  1. Zamknij eksperymentalne wystąpienie programu Visual Studio, jeśli jest uruchomione.

  2. Dodaj plik o nazwie MBConsumer\Dsl\Custom.cs i ustaw jego zawartość na następującą:

    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. Naciśnij klawisze Ctrl+F5.

  4. W eksperymentalnym wystąpieniu programu Visual Studio otwórz plik Debugging\Sample.consume.

  5. Kliknij dwukrotnie jeden kształt.

    Jeśli dla tego elementu ustawiono MBR, zostanie otwarty przywołyżony model i zostanie wybrany przywołyny element.

Uwaga

Składnik Przekształcanie szablonu tekstu jest automatycznie instalowany w ramach obciążenia programistycznego rozszerzenia programu Visual Studio. Można go również zainstalować na karcie Poszczególne składniki Instalator programu Visual Studio w kategorii Zestawy SDK, biblioteki i struktury. Zainstaluj składnik Zestawu SDK modelowania na karcie Poszczególne składniki.