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.
Wenn die DSL-Ziellösung kein ModelBusAdapter-Projekt enthält, erstellen Sie eines mithilfe des Assistenten für die ModelBus-Erweiterung:
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.
Öffnen Sie die DSL-Definitionsdatei. Klicken Sie mit der rechten Maustaste auf die Designoberfläche und klicken Sie dann auf ModelBus aktivieren.
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.
Klicken Sie auf OK. Der DSL-Projektmappe wird ein neues ModelBusAdapter-Projekt hinzugefügt.
Klicken Sie auf Alle Vorlagen transformieren.
Generieren Sie die Projektmappe neu.
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:
Kopieren Sie im Windows-Explorer den Ordner, der ModelBusAdapter.csproj enthält, und fügen Sie ihn ein.
Benennen Sie die Projektdatei um (z. B. in T4ModelBusAdapter.csproj).
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.
Ändern Sie in jeder
*.tt
-Datei des neuen Projekts den Namespace.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.
Fügen Sie im DslPackage-Projekt einen Verweis auf das neue Adapterprojekt hinzu, damit es Verweise auf beide Adapter enthält.
Fügen Sie in DslPackage\source.extension.tt eine Zeile hinzu, die auf Ihr neues Adapterprojekt verweist.
<MefComponent>|T4ModelBusAdapter|</MefComponent>
Alle Vorlagen transformieren und erstellen Sie die Projektmappe neu. Es sollten keine Buildfehler auftreten.
Fügen Sie im neuen Adapterprojekt Verweise auf die folgenden Assemblys hinzu:
- Microsoft.VisualStudio.TextTemplating.11.0
- Microsoft.VisualStudio.TextTemplating.Modeling.11.0
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.
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:
Erstellen zweier DSLs. Eine DSL, der Consumer, verfügt über die Eigenschaft
ModelBusReference
, die auf die andere DSL, den Provider, verweisen kann.Erstellen Sie zwei ModelBus-Adapter im Provider: einen für den Zugriff durch Textvorlagen, der andere für gewöhnlichen Code.
Erstellen Sie Instanzmodelle der DSLs in einem einzelnen experimentellen Projekt.
Legen Sie eine Domäneneigenschaft in einem Modell so fest, dass sie auf das andere Modell verweist.
Schreiben Sie einen Doppelklickhandler, der das Modell öffnet, auf das verwiesen wird.
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
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.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.
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
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.
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.
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
.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
Fügen Sie im Projekt
DslPackage
einen Projektverweis aufT4ModelBusAdapter
ein.Fügen Sie in DslPackage\source.extension.tt die folgende Zeile unter
<Content>
hinzu.<MefComponent>|T4ModelBusAdapter|</MefComponent>
Fügen Sie im Projekt
T4ModelBusAdapter
einen Verweis auf Microsoft.VisualStudio.TextTemplating.Modeling.11.0 hinzu.Öffnen Sie T4ModelBusAdapter\AdapterManager.tt:
Ä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 {
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 { }
Klicken Sie auf der Titelleiste des Projektmappen-Explorers auf Alle Vorlagen transformieren.
Drücken Sie F5.
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
Erstellen Sie eine neue DSL mithilfe der Projektmappenvorlage „Minimale Sprache“. Nennen Sie die Sprache MBConsumer und legen Sie die Dateinamenerweiterung auf „.consume“ fest.
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 SieMBProvider\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.
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.
Fügen Sie in der
ExampleElement
-Klasse eine neue Domäneneigenschaft namensMBR
hinzu und legen Sie im Eigenschaftenfenster ihren Typ aufModelBusReference
fest.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.
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
Drücken Sie in der Projektmappe „MBConsumer“ STRG+F5. Eine experimentelle Instanz von Visual Studio wird im Projekt MBConsumer\Debugging geöffnet.
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.
Klicken Sie mit der rechten Maustaste auf das Debuggingprojekt, zeigen Sie auf Hinzufügen, und klicken Sie dann auf Vorhandenes Element.
Legen Sie im Dialogfeld Element hinzufügen den Filter auf Alle Dateien (*.*) fest.
Navigieren Sie zu
MBProvider\Debugging\Sample.provide
und klicken Sie dann auf Hinzufügen.
Öffnen Sie
Sample.consume
.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.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
Ö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
undinherits
dertemplate
-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.
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
Schließen Sie die experimentelle Instanz von Visual Studio, falls sie ausgeführt wird.
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); } } } } }
Drücken Sie STRG+F5.
Öffnen Sie
Debugging\Sample.consume
in der experimentellen Instanz von Visual Studio.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.
Zugehöriger Inhalt
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.