Utilizzo di ModelBus di Visual Studio in un modello di testo
Se si scrivono modelli di testo che leggono un modello contenente riferimenti a ModelBus di Visual Studio, è possibile risolvere i riferimenti per accedere ai modelli di destinazione. In tal caso, è necessario adattare i modelli di testo e le lingue specifiche del dominio a cui si fa riferimento:In that case, you have to adapt the text templates and the referenced domain-specific languages (DSLs):
Il linguaggio DSL di destinazione dei riferimenti deve avere un adapter ModelBus configurato per l'accesso dai modelli di testo. Se si accede anche al linguaggio DSL da altro codice, l'adattatore riconfigurato è necessario oltre all'adapter ModelBus standard.
La gestione adapter deve ereditare da VsTextTemplatingModelingAdapterManager e deve avere l'attributo
[HostSpecific(HostName)]
.Il modello deve ereditare da ModelBusEnabledTextTransformation.
Nota
Se si desidera leggere modelli DSL che non contengono riferimenti ModelBus, è possibile usare i processori di direttiva generati nei progetti DSL. Per altre informazioni, vedere Accesso ai modelli da modelli di testo.
Per altre informazioni sui modelli di testo, vedere Generazione di codice in fase di progettazione tramite modelli di testo T4.
Creare un adattatore bus di modello per l'accesso da modelli di testo
Per risolvere un riferimento ModelBus in un modello di testo, il linguaggio DSL di destinazione deve avere una scheda compatibile. I modelli di testo vengono eseguiti in un AppDomain separato dagli editor di documenti di Visual Studio e pertanto l'adattatore deve caricare il modello anziché accedervi tramite DTE.
Se la soluzione DSL di destinazione non dispone di un progetto ModelBusAdapter , crearne uno usando la procedura guidata estensione Modelbus:
Scaricare e installare l'estensione ModelBus di Visual Studio, se non è già stato fatto. Per altre informazioni, vedere Visualizzazione e modellazione SDK.
Aprire il file di definizione del linguaggio specifico di dominio. Fare clic con il pulsante destro del mouse sull'area di progettazione e quindi scegliere Abilita modelbus.
Nella finestra di dialogo selezionare I want to expose this DSL to the ModelBus (I want to expose this DSL to the ModelBus). È possibile selezionare entrambe le opzioni se si desidera che questo linguaggio DSL esponga i relativi modelli e di utilizzare riferimenti ad altri DSL.
Fare clic su OK. Un nuovo progetto "ModelBusAdapter" verrà aggiunto alla soluzione relativa al linguaggio specifico di dominio.
Fare clic su Trasforma tutti i modelli.
Ricompila la soluzione.
Se si vuole accedere al linguaggio DSL sia da un modello di testo che da altro codice, ad esempio il comando, duplicare il progetto ModelBusAdapter :
In Esplora risorse copiare e incollare la cartella contenente ModelBusAdapter.csproj.
Rinominare il file di progetto( ad esempio, in T4ModelBusAdapter.csproj).
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo della soluzione, scegliere Aggiungi e quindi fare clic su Progetto esistente. Individuare il nuovo progetto adattatore T4ModelBusAdapter.csproj.
In ogni
*.tt
file del nuovo progetto modificare lo spazio dei nomi .Fare clic con il pulsante destro del mouse sul nuovo progetto in Esplora soluzioni e quindi scegliere Proprietà. Nell'editor delle proprietà modificare i nomi dell'assembly generato e dello spazio dei nomi predefinito.
Nel progetto DslPackage aggiungere un riferimento al nuovo progetto adapter in modo che contenga riferimenti a entrambe le schede.
In DslPackage\source.extension.tt aggiungere una riga che faccia riferimento al nuovo progetto di adattatore.
<MefComponent>|T4ModelBusAdapter|</MefComponent>
Trasformare tutti i modelli e ricompilare la soluzione. Non devono verificarsi errori di compilazione.
Nel nuovo progetto adapter aggiungere riferimenti agli assembly seguenti:
- Microsoft.VisualStudio.TextTemplating.11.0
- Microsoft.VisualStudio.TextTemplating.Modeling.11.0
In AdapterManager.tt:
Modificare la dichiarazione di AdapterManagerBase in modo che erediti da VsTextTemplatingModelingAdapterManager.
public partial class <#= dslName =>AdapterManagerBase :
Microsoft.VisualStudio.TextTemplating.Modeling.VsTextTemplatingModelingAdapterManager { ...
Alla fine del file sostituire l'attributo HostSpecific prima della classe AdapterManager. Rimuovere la riga seguente:
[DslIntegration::HostSpecific(DslIntegrationShell::VsModelingAdapterManager.HostName)]
Inserire la riga seguente:
[Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]
Questo attributo filtra il set di adattatori disponibili quando un consumer modelbus cerca un adattatore.
Trasformare tutti i modelli e ricompilare la soluzione. Non devono verificarsi errori di compilazione.
Scrivere un modello di testo in grado di risolvere i riferimenti modelbus
In genere, si inizia con un modello che legge e genera file da un DSL "di origine". Questo modello usa la direttiva generata nel progetto DSL di origine per leggere i file del modello di origine nel modo descritto in Accesso ai modelli di testo. Tuttavia, il linguaggio DSL di origine contiene riferimenti ModelBus a un dsl di destinazione. Si vuole quindi abilitare il codice del modello per risolvere i riferimenti e accedere al linguaggio DSL di destinazione. È quindi necessario adattare il modello seguendo questa procedura:
Modificare la classe di base del modello in ModelBusEnabledTextTransformation.
Includere
hostspecific="true"
nella direttiva del modello.Aggiungere i riferimenti all'assembly al linguaggio DSL di destinazione e alla relativa scheda e per abilitare ModelBus.
Non è necessaria la direttiva generata come parte del dsl di destinazione.
<#@ 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.
#>
Quando viene eseguito questo modello di testo, la SourceDsl
direttiva carica il file Sample.source
. Il modello può accedere agli elementi del modello, a partire da this.ModelRoot
. Il codice può usare le classi di dominio e le proprietà del linguaggio DSL.
Inoltre, il modello può risolvere i riferimenti ModelBus. Dove i riferimenti puntano al modello di destinazione, le direttive assembly consentono al codice di usare le classi di dominio e le proprietà del linguaggio DSL del modello.
Se non si usa una direttiva generata da un progetto DSL, è necessario includere anche quanto segue.
<#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.11.0" #> <#@ assembly name = "Microsoft.VisualStudio.TextTemplating.Modeling.11.0" #>
Usare
this.ModelBus
per ottenere l'accesso a ModelBus.
Procedura dettagliata: Test di un modello di testo che usa ModelBus
In questa procedura dettagliata seguire questa procedura:
Costruire due DSL. Un linguaggio DSL, consumer, ha una
ModelBusReference
proprietà che può fare riferimento all'altro linguaggio DSL, il provider.Creare due adattatori ModelBus nel provider: uno per l'accesso tramite modelli di testo, l'altro per il codice ordinario.
Creare modelli di istanza dei DSLS in un singolo progetto sperimentale.
Impostare una proprietà di dominio in un modello in modo che punti all'altro modello.
Scrivere un gestore di doppio clic che apre il modello a cui punta.
Scrivere un modello di testo in grado di caricare il primo modello, seguire il riferimento all'altro modello e leggere l'altro modello.
Costruire un linguaggio DSL accessibile a ModelBus
Creare una nuova soluzione DSL. Per questo esempio, selezionare il modello di soluzione Flusso di attività. Impostare il nome della lingua su
MBProvider
e l'estensione del nome file su ".provide".Nel diagramma di definizione DSL fare clic con il pulsante destro del mouse su una parte vuota del diagramma che non si trova nella parte superiore e quindi scegliere Abilita modelbus.
Se non viene visualizzato Enable Modelbus, scaricare e installare l'estensione VMSDK ModelBus.
Nella finestra di dialogo Abilita Modelbus selezionare Esporre questo DSL al ModelBus e quindi fare clic su OK.
Alla soluzione viene aggiunto un nuovo progetto,
ModelBusAdapter
, .
È ora disponibile un linguaggio DSL accessibile dai modelli di testo tramite ModelBus. I riferimenti a esso possono essere risolti nel codice dei comandi, dei gestori eventi o delle regole, che operano nell'AppDomain dell'editor di file del modello. Tuttavia, i modelli di testo vengono eseguiti in un AppDomain separato e non possono accedere a un modello quando viene modificato. Se si desidera accedere ai riferimenti ModelBus a questo linguaggio DSL da un modello di testo, è necessario disporre di un ModelBusAdapter separato.
Creare un adapter ModelBus configurato per i modelli di testo
In Esplora file copiare e incollare la cartella contenente ModelBusAdapter.csproj.
Assegnare alla cartella il nome T4ModelBusAdapter.
Rinominare il file di progetto T4ModelBusAdapter.csproj.
In Esplora soluzioni aggiungere T4ModelBusAdapter alla soluzione MBProvider. Fare clic con il pulsante destro del mouse sul nodo della soluzione, scegliere Aggiungi e quindi fare clic su Progetto esistente.
Fare clic con il pulsante destro del mouse sul nodo del progetto T4ModelBusAdapter e quindi scegliere Proprietà. Nella finestra delle proprietà del progetto modificare il nome dell'assembly e lo spazio dei nomi predefinito in
Company.MBProvider.T4ModelBusAdapters
.In ogni file *.tt in T4ModelBusAdapter inserire "T4" nell'ultima parte dello spazio dei nomi, in modo che la riga sia simile alla seguente.
namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>.T4ModelBusAdapters
DslPackage
Nel progetto aggiungere un riferimento al progetto aT4ModelBusAdapter
.In DslPackage\source.extension.tt aggiungere la riga seguente in
<Content>
.<MefComponent>|T4ModelBusAdapter|</MefComponent>
T4ModelBusAdapter
Nel progetto aggiungere un riferimento a: Microsoft.VisualStudio.TextTemplating.Modeling.11.0Aprire T4ModelBusAdapter\AdapterManager.tt:
Modificare la classe di base di AdapterManagerBase in VsTextTemplatingModelingAdapterManager. Questa parte del file è ora simile alla seguente.
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 {
Nella parte finale del file inserire l'attributo aggiuntivo seguente davanti alla classe AdapterManager.
[Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]
Il risultato è simile al seguente.
/// <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 { }
Fare clic su Trasforma tutti i modelli nella barra del titolo di Esplora soluzioni.
Premere F5.
Verificare che il linguaggio DSL funzioni. Nel progetto sperimentale aprire
Sample.provider
. Chiudere l'istanza sperimentale di Visual Studio.I riferimenti modelbus a questo linguaggio DSL possono ora essere risolti nei modelli di testo e anche nel codice comune.
Costruire un linguaggio DSL con una proprietà di dominio ModelBus Reference
Creare un nuovo linguaggio DSL usando il modello di soluzione Linguaggio minimo. Denominare la lingua MBConsumer e impostare l'estensione del nome file su ".consume".
Nel progetto DSL aggiungere un riferimento all'assembly DSL MBProvider. Fare clic con il pulsante destro del mouse
MBConsumer\Dsl\References
e quindi scegliere Aggiungi riferimento. Nella scheda Sfoglia individuareMBProvider\Dsl\bin\Debug\Company.MBProvider.Dsl.dll
In questo modo è possibile creare codice che usa l'altro linguaggio DSL. Se si desidera creare riferimenti a diversi DSL, aggiungerli anche.
Nel diagramma di definizione DSL fare clic con il pulsante destro del mouse sul diagramma e quindi scegliere Abilita ModelBus. Nella finestra di dialogo selezionare Abilita questo dsl per utilizzare ModelBus.
Nella classe
ExampleElement
aggiungere una nuova proprietàMBR
di dominio e nella Finestra Proprietà impostarne il tipo suModelBusReference
.Fare clic con il pulsante destro del mouse sulla proprietà di dominio nel diagramma e quindi scegliere Modifica proprietà specifiche modelBusReference. Nella finestra di dialogo selezionare un elemento del modello.
Impostare il filtro della finestra di dialogo file come segue.
Provider File|*.provide
La sottostringa dopo "|" è un filtro per la finestra di dialogo di selezione file. È possibile impostarlo per consentire qualsiasi file usando *.*
Nell'elenco Tipo di elemento modello immettere i nomi di una o più classi di dominio nel linguaggio DSL del provider, ad esempio Company.MBProvider.Task. Possono essere classi astratte. Se si lascia vuoto l'elenco, l'utente può impostare il riferimento a qualsiasi elemento.
Chiudere la finestra di dialogo e trasformare tutti i modelli.
È stato creato un linguaggio DSL che può contenere riferimenti agli elementi in un altro linguaggio DSL.
Creare un riferimento ModelBus a un altro file nella soluzione
Nella soluzione MBConsumer premere CTRL+F5. Viene aperta un'istanza sperimentale di Visual Studio nel progetto MBConsumer\Debugging .
Aggiungere una copia di Sample.provide al progetto MBConsumer\Debugging . Ciò è necessario perché un riferimento ModelBus deve fare riferimento a un file nella stessa soluzione.
Fare clic con il pulsante destro del mouse sul progetto debug, scegliere Aggiungi e quindi fare clic su Elemento esistente.
Nella finestra di dialogo Aggiungi elemento impostare il filtro su Tutti i file (*.*).
Passare a
MBProvider\Debugging\Sample.provide
e quindi fare clic su Aggiungi.
Sample.consume
aperti.Fare clic su una forma di esempio e nella Finestra Proprietà fare clic su [...] nella proprietà MBR. Nella finestra di dialogo fare clic su Sfoglia e selezionare
Sample.provide
. Nella finestra degli elementi espandere il tipo Task e selezionare uno degli elementi.Salvare il file. Non chiudere ancora l'istanza sperimentale di Visual Studio.
È stato creato un modello che contiene un riferimento ModelBus a un elemento in un altro modello.
Risolvere un riferimento ModelBus in un modello di testo
Nell'istanza sperimentale di Visual Studio aprire un file di modello di testo di esempio. Impostarne il contenuto come indicato di seguito.
<#@ 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 #> <# } } #>
Notare i punti seguenti:
Gli
hostSpecific
attributi einherits
dellatemplate
direttiva devono essere impostati.L'accesso al modello consumer avviene normalmente tramite il processore di direttiva generato nel linguaggio DSL.
Le direttive assembly e import devono essere in grado di accedere a ModelBus e ai tipi del linguaggio DSL del provider.
Se si sa che molti MBR sono collegati allo stesso modello, è preferibile chiamare CreateAdapter una sola volta.
Scegliere Salva per salvare il modello. Verificare che il file di testo risultante sia simile al seguente.
ExampleElement1 ExampleElement2 ExampleElement2 is linked to Task: Task2
Risolvere un riferimento ModelBus in un gestore movimenti
Chiudere l'istanza sperimentale di Visual Studio, se è in esecuzione.
Aggiungere un file denominato MBConsumer\Dsl\Custom.cs e impostarne il contenuto come segue:
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); } } } } }
Premere CTRL+F5.
Nell'istanza sperimentale di Visual Studio aprire
Debugging\Sample.consume
.Fare doppio clic su una forma.
Se è stato impostato l'MBR su tale elemento, viene aperto il modello a cui si fa riferimento e viene selezionato l'elemento a cui si fa riferimento.
Contenuto correlato
- Integrazione di modelli tramite ModelBus di Visual Studio
- Generazione di codice e modelli di testo T4
Nota
Il componente Trasformazione modello di testo viene installato automaticamente come parte del carico di lavoro sviluppo di estensioni di Visual Studio. È anche possibile installarlo dalla scheda Singoli componenti di Programma di installazione di Visual Studio, nella categoria SDK, librerie e framework. Installare il componente Modeling SDK dalla scheda Singoli componenti .