Diretiva de modelo T4
Um modelo de texto T4 do Visual Studio normalmente começa com uma diretiva template
, que especifica como o modelo deve ser processado. Não deve haver mais de uma diretiva de modelo em um modelo de texto e nos arquivos que ele contenha.
Para obter uma visão geral da escrita de modelos de texto, confira Escrevendo um modelo de texto T4.
<#@ template [language="VB"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] [visibility="internal"] [linePragmas="false"] #>
A diretiva template
tem vários atributos que permitem especificar diferentes aspectos da transformação. Todos os atributos são opcionais.
Exemplo:
compilerOptions="optimize+"
Valores válidos:
Algumas opções válidas do compilador.
Ignorada para modelos de tempo de execução (pré-processados).
Essas opções são aplicadas quando o modelo for convertido em Visual C# ou Visual Basic, e o código resultante é compilado.
Exemplo:
culture="de-CH"
Valores válidos:
"", a cultura invariável, que é o padrão.
Uma cultura expressa como uma cadeia de caracteres no formato xx-XX. Por exemplo, en-US, ja-JP, de-CH, de-DE. Para obter mais informações, consulte System.Globalization.CultureInfo.
O atributo culture especifica a cultura a ser usada quando um bloco de expressão é convertido em texto.
Exemplo:
debug="true"
Valores válidos:
true
false
(padrão)
Se o atributo debug
for true
, o arquivo de código intermediário conterá informações que permitem que o depurador identifique mais especificamente a posição em seu modelo onde ocorreu uma quebra ou uma exceção.
Para modelos de tempo de design, o arquivo de código intermediário será gravado no diretório %TEMP%.
Para executar um modelo de tempo de design no depurador, salve o modelo de texto, abra o menu de atalho do modelo de texto no Gerenciador de Soluções e escolha Depurar Modelo T4.
Exemplo:
hostspecific="true"
Valores válidos:
true
false
(padrão)
trueFromBase
Se você definir o valor desse atributo como true
, uma propriedade chamada Host
será adicionado à classe gerada pelo modelo de texto. A propriedade é uma referência ao host do mecanismo de transformação e é declarada como ITextTemplatingEngineHost. Se você definiu um host personalizado, pode convertê-lo no tipo de host personalizado.
Como o tipo dessa propriedade depende do tipo de host, ele só é útil se você estiver gravando um modelo de texto que funciona somente com um host específico. É aplicável a modelos de tempo de design, mas não a modelos runtime.
Quando hostspecific
for true
, e você estiver usando o Visual Studio, poderá converter this.Host
em IServiceProvider para acessar recursos do Visual Studio. Você também pode usar Host.ResolvePath(filename)
para obter o caminho absoluto de um arquivo no projeto. Por exemplo:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<# // Get the Visual Studio API as a service:
DTE dte = ((IServiceProvider)this.Host).GetCOMService(typeof(DTE)) as DTE;
#>
Number of projects in this solution: <#= dte.Solution.Projects.Count #>
<#
// Find a path within the current project:
string myFile = File.ReadAllText(this.Host.ResolvePath("MyFile.txt"));
#>
Content of myFile is:
<#= myFile #>
Se você usar os atributos inherits
e hostspecific
juntos, especifique host="trueFromBase" na classe derivada e host="true” na classe base. Isso evita uma definição dupla da propriedade Host
no código gerado.
Exemplo:
language="VB"
Valores válidos:
C#
(padrão)
VB
O atributo language
especifica a linguagem (Visual Basic ou Visual C#) a ser usada para o código-fonte em blocos de instruções e expressões. O arquivo de código intermediário do qual o resultado é gerado usará essa linguagem. Essa linguagem não está relacionada à linguagem que seu modelo gera, que pode ser qualquer tipo de texto.
Por exemplo:
<#@ template language="VB" #>
<#@ output extension=".txt" #>
Squares of numbers:
<#
Dim number As Integer
For number = 1 To 4
#>
Square of <#= number #> is <#= number * number #>
<#
Next number
#>
Você pode especificar se o código do programa de seu modelo pode herdar de outra classe, que também pode ser gerado de um modelo de texto.
Você pode usar a herança entre modelos do texto de tempo de execução para criar um modelo básico que tenha muitas variantes derivadas. Os modelos de tempo de execução são aqueles que têm a propriedade Custom Tool definida para TextTemplatingFilePreprocessor. Um modelo de tempo de execução gerencia o código que você pode chamar em seu aplicativo criar o texto definido no modelo. Para obter mais informações, confira Geração de texto em tempo de execução com modelos de texto T4.
Se você não especificar um atributo inherits
, uma classe base e uma classe derivada serão geradas a partir de seu modelo de texto. Quando você especificar um atributo inherits
, somente a classe derivada será gerada. Você pode escrever uma classe base manualmente, mas deve fornecer os métodos usados pela classe derivada.
Normalmente, você especifica outro modelo pré-processado como a classe base. O modelo de base fornece os blocos de texto comuns, que podem ser intercalados com o texto dos modelos derivados. Você pode usar blocos de recursos de classe <#+ ... #>
para definir os métodos que contêm fragmentos de texto. Por exemplo, você pode colocar o framework dp texto de saída no modelo de base, fornecendo métodos virtuais que podem ser substituídos em modelos derivados:
Modelo de texto de tempo de execução (pré-processado) BaseTemplate.tt:
This is the common header.
<#
SpecificFragment1();
#>
A common central text.
<#
SpecificFragment2();
#>
This is the common footer.
<#+
// Declare abstract methods
protected virtual void SpecificFragment1() { }
protected virtual void SpecificFragment2() { }
#>
Modelo de texto de tempo de execução (pré-processado) DerivedTemplate1.tt:
<#@ template language="C#" inherits="BaseTemplate" #>
<#
// Run the base template:
base.TransformText();
#>
<#+
// Provide fragments specific to this derived template:
protected override void SpecificFragment1()
{
#>
Fragment 1 for DerivedTemplate1
<#+
}
protected override void SpecificFragment2()
{
#>
Fragment 2 for DerivedTemplate1
<#+
}
#>
Código do aplicativo para invocar DerivedTemplate1:
Console.WriteLine(new DerivedTemplate().TransformText());
Saída resultante:
This is the common header.
Fragment 1 for DerivedTemplate1
A common central text.
Fragment 2 for DerivedTemplate1
This is the common footer.
Você pode criar a base e as classes derivadas em projetos diferentes. Lembre-se de adicionar o projeto ou assembly de base às referências do projeto derivado.
Você também pode usar uma classe escrita manualmente comum como a classe base. A classe base deve fornecer os métodos usados pela classe derivada.
Aviso
Se você usar os atributos inherits
e hostspecific
juntos, especifique hostspecific="trueFromBase" na classe derivada e host="true” na classe base. Isso evita uma definição dupla da propriedade Host
no código gerado.
Um modelo de texto de tempo de design é um arquivo cuja propriedade Custom Tool é definida para TextTemplatingFileGenerator. O modelo gera um arquivo de saída de código ou texto, que faz parte do seu projeto do Visual Studio. Para gerar o arquivo de saída, primeiro o modelo é convertido em um arquivo de código de programa intermediário, que você normalmente não vê. O atributo inherits
especifica a classe base para esse código intermediário.
Para um modelo de texto de tempo de design, você pode especificar qualquer classe base que é derivada de Microsoft.VisualStudio.TextTemplating.TextTransformation. Use a diretiva <#@assembly#>
para carregar o assembly ou projeto que contém a classe base.
Para obter mais informações, consulte o post sobre “herança em modelos de texto" no blog de Gareth Jones.
Exemplo:
linePragmas="false"
Valores válidos:
true
(padrão)
false
Definir esse atributo como false remove as marcas que identificam os números de linha no código gerado. Isso significa que o compilador relatará todos os erros usando os números de linha do código gerado. Isso fornece mais opções de depuração, pois você pode escolher depurar o modelo de texto ou o código gerado.
Esse atributo também pode ajudar se você descobrir que os nomes de arquivo absolutos em pragmas estão ofuscando mesclagens no controle do código-fonte.
Exemplo:
visibility="internal"
Valores válidos:
public
(padrão)
internal
Em um modelo de texto de runtime, isso define o atributo visibility da classe gerada. Por padrão, a classe faz parte da API pública do código, mas definir visibility="internal"
garante que somente seu código possa usar a classe text-generating.