Condividi tramite


Scrittura di un modello di testo T4

Un modello di testo contiene il testo che genererà in un secondo momento. Ad esempio, un modello che crea una pagina Web conterrà "<html>…" e tutte le altre parti standard di una pagina HTML. Nel modello sono inseriti blocchi di controllo, che sono frammenti di codice programma. I blocchi di controllo forniscono valori variabili e consentono la ripetizione e l'uso condizionale di parti di testo.

Questa struttura facilita lo sviluppo di un modello, perché consente di crearlo partendo da un prototipo del file generato e inserendo gradualmente blocchi di controllo che variano il risultato.

I modelli di testo sono costituiti dalle parti seguenti:

  • Direttive: elementi che controllano il modo in cui il modello viene elaborato.

  • Blocchi di testo: contenuto che viene copiato direttamente nell'output.

  • Blocchi di controllo: codice programma che inserisce valori variabili nel testo e controlla le parti di testo condizionali e ripetute.

Per provare gli esempi in questo argomento, copiarli in un file modello come descritto in Generazione di codice in fase di progettazione tramite modelli di testo T4. Dopo avere modificato il file modello, salvarlo, quindi controllare il file di output .txt.

Direttive

Le direttive del modello di testo forniscono istruzioni generali al motore del modello di testo relative alla generazione di codice di trasformazione e al file di output.

Ad esempio, la direttiva seguente specifica che il file di output deve avere l'estensione .txt:

<#@ output extension=".txt" #>

Per ulteriori informazioni sulle direttive, vedere Direttive di modello di testo T4.

Blocchi di testo

Un blocco di testo inserisce del testo direttamente nel file di output. Non esiste una formattazione speciale per i blocchi di testo. Ad esempio, dal modello di testo seguente sarà prodotto un file di testo che contiene il parola "Hello":

<#@ output extension=".txt" #>
Hello

Blocchi di controllo

I blocchi di controllo sono sezioni del codice programma che sono utilizzate per trasformare i modelli. La lingua predefinita è C#, ma per utilizzare Visual Basic, è possibile scrivere questa direttiva all'inizio del file:

<#@ template language="VB" #>

Il linguaggio nel quale si scrive il codice nei blocchi di controllo non è correlato al linguaggio del testo generato.

Blocchi di controllo standard

Un blocco di controllo standard è una sezione di codice programma che genera parte del file di output.

È possibile combinare qualsiasi numero di blocchi di testo e di blocchi di controllo standard in un file modello. Tuttavia, non è possibile inserire un blocco di controllo in un altro. Ciascun blocco di controllo standard è delimitato dai simboli <# ... #>.

Ad esempio, il blocco di controllo e il blocco di testo seguenti inseriscono nel file di output la riga "0, 1 2, 3 4 Hello"!:

<#
    for(int i = 0; i < 4; i++)
    {
        Write(i + ", ");
    }
    Write("4");

#> Hello!

Anziché utilizzare istruzioni Write() esplicite, è possibile interfogliare testo e codice. Nell'esempio seguente viene stampato "Hello!" per quattro volte:

<#
    for(int i = 0; i < 4; i++)
    {
#>
Hello!
<#
    } 
#>

È possibile inserire un blocco di testo ovunque sia possibile inserire nel codice un'istruzione Write();.

Nota

Quando si incorpora un blocco di testo all'interno di un'istruzione composta, quale un ciclo o un'istruzione condizionale, utilizzare sempre le parentesi graffe {...} per contenere il blocco di testo.

Blocchi di controllo dell'espressione

Un blocco di controllo dell'espressione valuta un'espressione e la converte in una stringa. Tale stringa viene inserita nel file di output.

I blocchi di controllo dell'espressione sono delimitati dai simboli <#= ... #>

Ad esempio, il blocco di controllo seguente inserisce nel file di output "5":

<#= 2 + 3 #>

Si noti che il simbolo di apertura è costituito da tre caratteri" < #= ".

L'espressione può includere qualsiasi variabile che è nell'ambito. Ad esempio, questo blocco stampa righe con i numeri:

<#@ output extension=".txt" #>
<#
    for(int i = 0; i < 4; i++)
    {
#>
This is hello number <#= i+1 #>: Hello!
<#
    } 
#>

Blocchi di controllo della funzionalità di classe

Un blocco di controllo della funzionalità di classe definisce proprietà, metodi o qualsiasi altro codice che non deve essere incluso nella trasformazione principale. I blocchi della funzionalità di classe vengono spesso utilizzati per le funzioni di supporto. In genere, i blocchi della funzionalità di classe vengono inseriti in file distinti in modo che possano essere inclusi da più modelli di testo.

I blocchi di controllo della funzionalità di classe sono delimitati dai simboli <#+ ... #>

Ad esempio, nel file modello seguente viene dichiarato e utilizzato un metodo:

<#@ output extension=".txt" #>
Squares:
<#
    for(int i = 0; i < 4; i++)
    {
#>
    The square of <#= i #> is <#= Square(i+1) #>.
<#
    } 
#>
That is the end of the list.
<#+   // Start of class feature block
private int Square(int i)
{
    return i*i;
}
#>

È necessario posizionare le funzionalità di classe alla fine del file nel quale sono scritte. Tuttavia, si può <#@include#> un file che contiene una funzionalità di classe, anche se la direttiva include è seguita da blocchi standard e testo.

Per ulteriori informazioni sui blocchi di controllo, vedere Blocchi di controllo del modello di testo T4.

I blocchi della funzionalità di classe possono contenere blocchi di testo

È possibile scrivere un metodo che generi il testo. Ad esempio:

List of Squares:
<#
   for(int i = 0; i < 4; i++)
   {  WriteSquareLine(i); }
#>
End of list.
<#+   // Class feature block
private void WriteSquareLine(int i)
{
#>
   The square of <#= i #> is <#= i*i #>.
<#   
}
#>

È particolarmente utile posizionare un metodo che genera il testo in un file separato che possa essere incluso da più modelli.

Utilizzo di definizioni esterne

Assembly

I blocchi di codice del modello possono utilizzare tipi definiti gli assembly .NET di uso più comune, quali System.dll. Inoltre, è possibile fare riferimento ad altri assembly .NET o ad assembly propri. È possibile fornire un percorso o il nome sicuro di un assembly:

<#@ assembly name="System.Xml" #>

È necessario utilizzare nomi di percorso assoluto o nomi di macro standard nel nome del percorso. Ad esempio:

<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>

Per un elenco di macro, vedere Macro per comandi e proprietà di compilazione.

La direttiva dell'assembly non ha alcun effetto in un modello di testo pre-elaborato.

Per ulteriori informazioni, vedere Direttiva assembly T4.

Spazi dei nomi

La direttiva import è uguale alla clausola using in C# o alla clausola imports in Visual Basic. Consente di fare riferimento a tipi nel codice senza utilizzare un nome completo:

<#@ import namespace="System.Xml" #>

È possibile utilizzare tante direttive assembly e import quante se ne desidera. È necessario posizionarle prima dei blocchi di testo e di controllo.

Per ulteriori informazioni, vedere Direttiva import T4.

Includere codice e testo

La direttiva include inserisce il testo da un altro file modello. Ad esempio, questa direttiva inserisce il contenuto di test.txt.

<#@ include file="c:\test.txt" #>

Il contenuto incluso viene elaborato più o meno come se facesse parte del modello di testo che include. Tuttavia, è possibile includere un file che contiene un blocco della funzionalità di classe <#+...#> anche se la direttiva include è seguita da testo ordinario e blocchi di controllo standard.

Per ulteriori informazioni, vedere Direttiva include T4.

Metodi di utilità

In un blocco di controllo esistono numerosi metodi, quali Write(), sempre a disposizione. Tra questi vi sono metodi che consentono di impostare un rientro per l'output e per segnalare errori.

È inoltre possibile scrivere un proprio set di metodi di utilità.

Per ulteriori informazioni, vedere Metodi di utilità per i modelli di testo T4.

Trasformazione di dati e modelli

L'applicazione più utile per un modello di testo è la generazione di materiale sulla base del contenuto di un'origine, quale un modello, un database o un file di dati. Il modello estrae e riformatta i dati. Una raccolta di modelli può trasformare tale origine in più file.

Esistono molti approcci alla lettura del file di origine.

Leggere un file nel modello di testo. Si tratta del modo più semplice per ottenere i dati nel modello:

<#@ import namespace="System.IO" #>
<# string fileContent = File.ReadAllText(@"C:\myData.txt"); ...

Caricare un file come modello navigabile. Un metodo più efficace è quello di leggere i dati come un modello, nel quale il codice del modello di testo può navigare. Ad esempio, è possibile caricare un file XML e spostarsi al suo interno utilizzando espressioni XPath. È inoltre possibile utilizzare xsd.exe per creare un set di classi con il quale leggere i dati XML.

Modificare il file modello in diagramma o un form. Domain-Specific Language Tools offre strumenti che consentono di modificare un modello come un diagramma o un form di Windows. In questo modo diventa più semplice discutere il modello con gli utenti dell'applicazione generata. Domain-Specific Language Tools crea anche un set di classi fortemente tipizzate che riflette la struttura del modello. Per ulteriori informazioni, vedere Generazione di codice da un linguaggio specifico di dominio.

Utilizzare un modello UML. È possibile generare codice da un modello UML. Il vantaggio consiste nel fatto che il modello può essere modificato come un diagramma in una notazione familiare. Inoltre, non è necessario progettare il diagramma. Per ulteriori informazioni, vedere Procedura: generare file da un modello UML.

Percorsi di file relativi

Se si desidera fare riferimento a un file in un percorso relativo al modello di testo, utilizzare this.Host.ResolvePath(). È inoltre necessario impostare hostspecific="true" nella direttiva template:

<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="System.IO" #>
<#
 // Find a path within the same project as the text template:
 string myFile = File.ReadAllText(this.Host.ResolvePath("MyFile.txt"));
#>
Content of MyFile.txt is:
<#= myFile #>

È inoltre possibile ottenere altri servizi forniti dall'host. Per ulteriori informazioni, vedere Accesso a Visual Studio o altri host da un modello di testo T4.

Modelli di testo eseguiti in un AppDomain separato

È necessario tenere presente che un modello di testo viene eseguito in un AppDomain separato dall'applicazione principale. Nella maggior parte dei casi questo non è importante, ma in determinati casi complessi è possibile individuare restrizioni. Ad esempio, se si desidera passare i dati all'intero o all'esterno del modello da un servizio separato, il servizio deve fornire un'API serializzabile.

Modifica dei modelli

È possibile scaricare editor modelli di testo specializzati dalla Raccolta online di Gestione estensioni. Scegliere Gestione estensioni dal menu Strumenti. Fare clic su Raccolta online, quindi utilizzare lo strumento di ricerca.

Argomenti correlati

Attività

Argomento

Scrittura di un modello.

Linee guida per la scrittura di modelli di testo T4

Generare del testo utilizzando codice programma.

Scrittura di un modello di testo T4

Generare file in una soluzione Visual Studio.

Generazione di codice in fase di progettazione tramite modelli di testo T4

Eseguire generazione di testo fuori da Visual Studio.

Generazione di file con l'utilità TextTransform

Trasformare i dati nel formato di un linguaggio specifico di dominio.

Generazione di codice da un linguaggio specifico di dominio

Scrivere processori di direttive per trasformare le proprie origini dati.

Personalizzazione della trasformazione del testo T4

Cronologia delle modifiche

Data

Cronologia

Motivo

Marzo 2011

Utilizzare macro nella direttiva dell'assembly.

Commenti e suggerimenti dei clienti.