Partilhar via


Geração de texto de tempo de execução usando os modelos de texto T4

Você pode gerar cadeias de caracteres de texto em seu aplicativo em tempo de execução usando Visual Studio pré-processado modelos de texto. O computador onde o aplicativo é executado não tem ter Visual Studio. Pré-processado modelos são chamados de "modelos de texto em tempo de execução".

Cada modelo é uma mistura de texto, como ele aparecerá na seqüência de caracteres gerada e fragmentos de código de programa. Os fragmentos de programa fornecem valores para as partes a variáveis da seqüência de caracteres e também controlam partes condicionais e repetidos.

Por exemplo, o modelo a seguir pode ser usado em um aplicativo que cria um relatório HTML.

<#@ template language="C#" #>
<html><body>
<h1>Sales for Previous Month</h2>
<table>
    <# for (int i = 1; i <= 10; i++)
       { #>
         <tr><td>Test name <#= i #> </td>
             <td>Test value <#= i * i #> </td> </tr>
    <# } #>
 </table>

This report is Company Confidential.
</body></html>

Observe que o modelo é uma página HTML em que as partes a variáveis foram substituídas por código de programa. O design de uma página dessas poderia começar escrevendo um protótipo estático da página HTML. Em seguida, você poderia substituir a tabela e outras partes da variáveis com código de programa que gera o conteúdo que varia de uma vez para a próxima.

Usando um modelo em seu aplicativo faz é mais fácil de ver o formulário final da saída do que seria possível em, por exemplo, uma longa série de instruções de gravação. Fazer alterações no formulário da saída é mais fácil e confiável.

Criando um modelo de texto de tempo de execução em qualquer aplicativo

Para criar um modelo de texto em tempo de execução

  1. No Solution Explorer, clique com o botão direito do projeto, aponte para Adde em seguida, clique em Novo Item.

  2. No Add New Item caixa de diálogo, selecione Modelo de texto pré-processado. (Em Visual Basic procure em Items\General comuns.)

  3. Digite um nome para o seu arquivo de modelo.

    ObservaçãoObservação

    O nome de arquivo modelo será usado como um nome de classe no código gerado. Portanto, não devem ter espaços ou pontuação.

  4. Clique em Adicionar.

    Um novo arquivo é criado com extensão .tt. Sua Ferramenta personalizada for definida como TextTemplatingFilePreprocessor. Ele contém a seguinte linha:

    <#@ template language="C#" #>
    

Convertendo um arquivo existente a um modelo de tempo de execução

Uma boa maneira de criar um modelo é um exemplo existente da saída de converter. Por exemplo, se seu aplicativo irá gerar os arquivos HTML, você pode iniciar a criação de um arquivo HTML simples. Certifique-se de que ele funciona corretamente e se a sua aparência está correta. Em seguida, incluí-lo em seu Visual Studio de projeto e convertê-lo para um modelo.

Para converter um arquivo de texto existente em um modelo de tempo de execução

  1. Incluir o arquivo em seu Visual Studio project. No Solution Explorer, clique com o botão direito no projeto, aponte para Adde em seguida, clique em Item existente.

  2. Definir o arquivo Custom Tools propriedade para TextTemplatingFilePreprocessor. No Solution Explorer, clique com o botão direito no arquivo e clique em Propriedades.

    ObservaçãoObservação

    Se a propriedade já está definida, certifique-se de que ele é TextTemplatingFilePreprocessor e não TextTemplatingFileGenerator. Isso pode acontecer se você incluir um arquivo que já tem a extensão .tt.

  3. Altere a extensão de nome de arquivo para .tt. Embora esta etapa é opcional, ajuda evitar abrir o arquivo em um editor incorreto.

  4. Remova quaisquer espaços ou pontuação a principal parte do nome do arquivo. Por exemplo "My Web Page.tt" seria incorreto, mas o "MyWebPage.tt" está correto. O nome do arquivo será usado como um nome de classe no código gerado.

  5. Insira a seguinte linha no início do arquivo. Se você estiver trabalhando em um projeto de Visual Basic, substitua "C#" com "vb".

    <#@ template language="C#" #>

O conteúdo do modelo de tempo de execução

Diretiva de modelo

Como ele era quando você criou o arquivo, mantenha a primeira linha do modelo:

<#@ template language="C#" #>

O parâmetro de idioma dependerão de idioma do seu projeto.

Conteúdo simples

Editar o .tt o arquivo para conter o texto que você deseja que o seu aplicativo para gerar. Por exemplo:

<html><body>
<h1>Sales for January</h2>
<!-- table to be inserted here -->
This report is Company Confidential.
</body></html>

Código de programa incorporado

Você pode inserir o código de programa entre <# e #>. Por exemplo:

<table>
    <# for (int i = 1; i <= 10; i++)
       { #>
         <tr><td>Test name <#= i #> </td>
             <td>Test value <#= i * i #> </td> </tr>
    <# } #>
 </table>

<table>
<#
    For i As Integer = 1 To 10
#>
    <tr><td>Test name <#= i #> </td>
      <td>Test value <#= i*i #> </td></tr>
<#
    Next
#>
</table>

Observe que as declarações são inseridas entre <# ... #> e expressões são inseridas entre <#= ... #>. Para obter mais informações, consulte Escrever um modelo de texto T4.

Usando o modelo

O código criado a partir do modelo

Sempre que você salva o .tt arquivo, uma subsidiária .cs ou .vb será gerado o arquivo. Para ver este arquivo no Solution Explorer, expanda o .tt nó do arquivo. Em um projeto de Visual Basic, você poderá expandir o nó após você clicar em Mostrar todos os arquivos na barra de ferramentas do Solution Explorer.

Observe que este arquivo da subsidiária contém uma classe parcial que contém um método chamado TransformText(). Você pode chamar esse método a partir do seu aplicativo.

Gerando o texto em tempo de execução

No seu código do aplicativo, você pode gerar o conteúdo do modelo usando uma chamada como este:

MyWebPage page = new MyWebPage();
String pageContent = page.TransformText();
System.IO.File.WriteAllText("outputPage.html", pageContent);
Dim page = New My.Templates.MyWebPage
Dim pageContent = page.TransformText()
System.IO.File.WriteAllText("outputPage.html", pageContent)

Para colocar a classe gerada em um namespace específico, defina a Custom Tool namespace a propriedade do arquivo de modelo de texto.

Passando parâmetros no construtor

Normalmente um modelo deve importar alguns dados de outras partes do aplicativo. Para tornar fácil, o código criado pelo modelo é uma classe parcial. Você pode criar outra parte da mesma classe em outro arquivo em seu projeto. Esse arquivo pode incluir um construtor com parâmetros, propriedades e funções que podem acessadas pelo código que está incorporado no modelo e pelo restante do aplicativo.

Por exemplo, você pode criar um arquivo separado MyWebPageCode.cs:

partial class MyWebPage
{
    private MyData m_data;
    public MyWebPage(MyData data) { this.m_data = data; }}

No seu arquivo de modelo MyWebPage.tt, você poderia escrever:

<h2>Sales figures</h2>
<table>
<# foreach (MyDataItem item in m_data.Items) 
   // m_data is declared in MyWebPageCode.cs
   { #>
      <tr><td> <#= item.Name #> </td>
          <td> <#= item.Value #> </td></tr>
<# } // end of foreach
#>
</table>

Para usar este modelo no aplicativo:

MyData data = ...;
MyWebPage page = new MyWebPage(data);
String pageContent = page.TransformText();
System.IO.File.WriteAllText("outputPage.html", pageContent);

Parâmetros do construtor de Visual Basic

Em Visual Basico arquivo separado, MyWebPageCode.vb contém:

Namespace My.Templates
  Partial Public Class MyWebPage
    Private m_data As MyData
    Public Sub New(ByVal data As MyData)
      m_data = data
    End Sub
  End Class
End Namespace

O arquivo de modelo pode conter:

<#@ template language="VB" #>
<html><body>
<h1>Sales for January</h2>
<table>
<#
    For Each item In m_data.Items
#>
    <tr><td>Test name <#= item.Name #> </td>
      <td>Test value <#= item.Value #> </td></tr>
<#
    Next
#>
</table>

This report is Company Confidential.
</body></html>

E o modelo poderia ser chamado, passando o parâmetro no construtor:

Dim data = New My.Templates.MyData
    ' Add data values here ....
Dim page = New My.Templates.MyWebPage(data)
Dim pageContent = page.TransformText()
System.IO.File.WriteAllText("outputPage.html", pageContent)

Passando dados nas propriedades de modelo

Um método alternativo para passar dados para o modelo é adicionar propriedades públicas para a classe de modelo em uma definição de classe parcial. Seu aplicativo pode definir as propriedades antes de invocar TransformText().

Você também pode adicionar campos à sua classe de modelo em uma definição parcial. Isso permitiria que você passar dados entre as execuções sucessivas do modelo.

Usar classes parciais para código

Muitos desenvolvedores preferem evitar a escrita de grandes corpos de código nos modelos. Em vez disso, defina os métodos em uma classe parcial que tem o mesmo nome do arquivo de modelo. Chame esses métodos do modelo. Dessa forma, o modelo mostra mais claramente que a saída seqüência de destino terá a seguinte aparência. Discussões sobre a aparência do resultado podem ser separadas da lógica de criar os dados que ele exibe.

Assemblies e referências

Se desejar que o seu código de modelo para fazer referência a um.NET ou outro assembly como System.Xml.dll, você deve adicioná-lo ao seu projeto referências da maneira usual.

Se você deseja importar um namespace, da mesma forma como um using de instrução, você pode fazer isso com o import diretiva:

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

Essas diretivas devem ser colocadas no início do arquivo, imediatamente após o <#@template diretiva.

Conteúdo compartilhado

Se você tiver o texto que é compartilhado entre vários modelos, você pode colocá-lo em um arquivo separado e incluí-lo em cada arquivo no qual ele deverá aparecer:

<#@include file="CommonHeader.txt" #>

O conteúdo incluído pode conter qualquer combinação de código de programa e o texto sem formatação e ele pode conter outros incluem diretivas e outras diretivas.

A diretiva de inclusão pode ser usada em qualquer lugar dentro do texto de um arquivo de modelo ou um arquivo incluído.

Herança entre os modelos de texto de tempo de execução

Você pode compartilhar conteúdo entre os modelos de tempo de execução, escrevendo um modelo de classe base, que pode ser abstrato. Use o inherits parâmetro da <@#template#> a diretiva para fazer referência a outra classe de modelo pré-processado.

Padrão de herança: Fragmentos de métodos Base

No padrão usado no exemplo a seguir, observe os seguintes pontos:

  • A classe base SharedFragments define métodos dentro de blocos de recurso de classe <#+ ... #>.

  • A classe base não contém nenhum texto livre. Em vez disso, todos os seus blocos de texto ocorrerem dentro de métodos de classe de recurso.

  • A classe derivada invoca os métodos definidos na SharedFragments.

  • O aplicativo chama o TextTransform() o método da classe derivada, mas não não transformar a classe base SharedFragments.

  • As classes derivadas e base são os modelos de texto pré-processado: ou seja, o Ferramenta personalizada for definida como TextTemplatingFilePreprocessor.

SharedFragments.tt:

<#@ template language="C#" #>
<#+
protected void SharedText(int n)
{
#>
   Shared Text <#= n #>
<#+
}
// Insert more methods here if required.
#>

MyTextTemplate1.tt:

<#@ template language="C#" inherits="SharedFragments" #>
begin 1
   <# SharedText(2); #>
end 1

MyProgram.cs:

... 
MyTextTemplate1 t1  = new MyTextTemplate1();
string result = t1.TransformText();
Console.WriteLine(result);

A saída resultante:

begin 1
    Shared Text 2
end 1

Padrão de herança: Texto no corpo de Base

Nesta abordagem alternativa ao uso de herança do modelo, a maior parte do texto é definida no modelo de base. Os modelos de derivadas fornecem dados e fragmentos de texto que se enquadram o conteúdo de base.

AbstractBaseTemplate1.tt:

<#@ template language="C#" #>

Here is the description for this derived template:
  <#= this.Description #>

Here is the fragment specific to this derived template:
<# 
  this.PushIndent("  ");
  SpecificFragment(42); 
  this.PopIndent();
#>
End of common template.
<#+ 
  // State set by derived class before calling TextTransform:
  protected string Description = "";
  // 'abstract' method to be defined in derived classes:
  protected virtual void SpecificFragment(int n) { }
#>

DerivedTemplate1.tt:

<#@ template language="C#" inherits="AbstractBaseTemplate1" #>
<# 
  // Set the base template properties:
  base.Description = "Description for this derived class"; 

  // Run the base template:
  base.TransformText();


#>
End material for DerivedTemplate1.

<#+
// Provide a fragment specific to this derived template:

protected override void SpecificFragment(int n)
{
#>
   Specific to DerivedTemplate1 : <#= n #>
<#+
}
#>

Código do aplicativo:

... 
DerivedTemplate1 t1 = new DerivedTemplate1();
string result = t1.TransformText();
Console.WriteLine(result);

Saída resultante:

Here is the description for this derived template:
  Description for this derived class

Here is the fragment specific to this derived template:
     Specific to DerivedTemplate1 : 42
End of common template.
End material for DerivedTemplate1.
Observação importanteImportante

Se você estiver usando uma versão do Visual Studio anteriores à versão Beta do SP1, qualquer texto no modelo derivado que a saída é feito antes da chamada para base.TransformTemplate() não aparecerá na saída.

Tópicos relacionados

Modelos de tempo de design: Se você quiser usar um modelo para gerar o código que se torna parte do seu aplicativo, consulte Geração de código de tempo de design usando modelos de texto T4.

Modelos pré-processado podem ser usados em qualquer aplicativo onde os modelos e seu conteúdo são determinadas em tempo de compilação. Mas se você quiser escrever um Visual Studio extensão que gera o texto a partir de modelos que se alteram em tempo de execução, consulte Invocar a transformação de texto em uma extensão do VS.

Consulte também

Conceitos

Escrever um modelo de texto T4

Outros recursos

Modelos de texto T4 e de geração de código

Noções básicas sobre T4: Pré-processado modelos de texto por Oleg Sych

Histórico de alterações

Date

History

Motivo

Março de 2011

Foi adicionada a secção sobre a personalização com "inherits".

Aprimoramento de informações.

Outubro de 2010

Exemplos VB adicionados

Aprimoramento de informações.