Instrucciones para escribir plantillas de texto T4

Estas directrices generales pueden resultar útiles si se va a generar código de programa u otros recursos para aplicaciones en Visual Studio. No son reglas fijas.

Directrices para las plantillas T4 en tiempo de diseño

Las plantillas T4 en tiempo de diseño generan código en un proyecto de Visual Studio en tiempo de diseño. Para obtener más información, vea Generación de código en tiempo de diseño mediante plantillas de texto T4.

Genere aspectos variables de la aplicación.

La generación de código es especialmente útil para aquellos aspectos de la aplicación que pueden cambiar durante el proyecto o cambiar entre las diferentes versiones de la aplicación. Separe estos aspectos variables de los aspectos más fijos para que pueda determinar más fácilmente lo que se debe generar. Por ejemplo, si la aplicación proporciona un sitio web, separe las funciones estándar para dar servicio a la página de la lógica que define las rutas de navegación de una página a otra.

Codifique los aspectos variables en uno o varios modelos de origen.

Un modelo es un archivo o una base de datos que cada plantilla lee para obtener valores específicos para las partes variables del código que se van a generar. Los modelos pueden ser bases de datos, archivos XML que haya diseñado usted mismo, diagramas o lenguajes específicos del dominio. Normalmente, se usa un modelo para generar muchos archivos en cualquier proyecto de Visual Studio. Cada archivo se genera a partir de una plantilla independiente.

En los proyectos se puede usar más de un modelo. Por ejemplo, se puede definir un modelo para la navegación entre páginas web y otro modelo independiente para el diseño de las páginas.

Centre el modelo en las necesidades y el vocabulario de los usuarios, no en la implementación.

Por ejemplo, en una aplicación de sitio web, cabría esperar que el modelo haga referencia a páginas web e hipervínculos.

Lo ideal sería elegir una forma de presentación que se adapte al tipo de información que representa el modelo. Por ejemplo, un modelo de rutas de acceso para el desplazamiento por un sitio web podría ser un diagrama de cuadros y flechas.

Pruebe el código generado.

Use pruebas manuales o automatizadas para comprobar que el código resultante funciona tal como necesitan los usuarios. Evite generar pruebas a partir del mismo modelo desde el que se genera el código.

En algunos casos, las pruebas generales se pueden realizar directamente en el modelo. Por ejemplo, se puede escribir una prueba que garantice que se puede acceder a todas las páginas del sitio web desplazándose desde cualquier otra.

Permita código personalizado: genere clases parciales.

Permita el código que escriba a mano, además del código generado. No es usual que un esquema de generación de código pueda tener en cuenta todas las posibles variaciones que puedan surgir. Por consiguiente, debe esperar agregar o invalidar una parte del código generado. Cuando el material generado se encuentra en un lenguaje .NET como C# o Visual Basic, hay dos estrategias que son especialmente útiles:

  • Las clases generadas deben ser parciales. Esto le permite agregar contenido al código generado.

  • Las clases se deben generar en pares, y uno de ellos hereda del otro. La clase base debe contener todos los métodos y propiedades generados, y la clase derivada debe contener solo los constructores. Esto permite que el código escrito a mano invalide todos los métodos generados.

En otros lenguajes generados, como XML, use la directiva <#@include#> para realizar combinaciones sencillas entre el contenido escrito a mano y el generado. En casos más complejos, es posible que tenga que escribir un paso después del procesamiento que combine el archivo generado con los archivos escritos a mano.

Mueva el material común a archivos de inclusión o plantillas en tiempo de ejecución.

Para evitar repetir bloques de texto y código similares en varias plantillas, use la directiva <#@ include #>. Para más información, consulte Directiva Include T4.

También puede compilar plantillas de texto en tiempo de ejecución en un proyecto independiente y, después, llamarlas desde la plantilla en tiempo de diseño. Para ello, use la directiva <#@ assembly #> para acceder al proyecto independiente.

Considere la posibilidad de mover grandes bloques de código a un ensamblado independiente.

Si tiene bloques de código grandes y bloques de características de clase, puede resultar útil mover una parte de este código a métodos que se compilen en un proyecto independiente. Puede usar la directiva <#@ assembly #> para acceder al código de la plantilla. Para más información, consulte Directiva de ensamblado T4.

Puede colocar los métodos en una clase abstracta que la plantilla pueda heredar. La clase abstracta debe heredar de Microsoft.VisualStudio.TextTemplating.TextTransformation. Para más información, consulte Directivas de plantillas T4.

Genere código, no archivos de configuración.

Un método para escribir una aplicación de variable es escribir código de programa genérico que acepte un archivo de configuración. Las aplicaciones que se escriben así son muy flexibles y si cambian los requisitos empresariales, se puede volver a configurar tener que volver a compilarlas. Sin embargo, un inconveniente de este enfoque es que la aplicación funcionará peor que una aplicación más específica. Además, su código de programa será más difícil de leer y mantener, en parte porque siempre tiene que tratar con los tipos más genéricos.

Por el contrario, una aplicación cuyos elementos variables se generan antes de la compilación puede estar fuertemente tipada. Esto hace que sea mucho más fácil y confiable escribir código a mano e integrarlo con las partes generadas del software.

Para obtener todas las ventajas de la generación de código, intente generar código de programa, en lugar de archivos de configuración.

Use una carpeta Código generado.

Coloque las plantillas y los archivos generados en una carpeta de proyecto denominada Código generado, con el fin de que saber que los archivos que contenga no se deben editar directamente. Si crea código personalizado para reemplazar o agregarlo a las clases generadas, coloque esas clases en una carpeta denominada Código personalizado. Esta es la estructura de un proyecto típico:

MyProject
   Custom Code
      Class1.cs
      Class2.cs
   Generated Code
      Class1.tt
          Class1.cs
      Class2.tt
          Class2.cs
   AnotherClass.cs

Directrices para plantillas T4 de tiempo de ejecución (preprocesadas)

Mueva el material común a las plantillas heredadas.

Puede usar la herencia para compartir métodos y bloques de texto entre plantillas de texto T4. Para más información, consulte Directivas de plantillas T4.

También puede usar archivos de inclusión que tengan plantillas en tiempo de ejecución.

Mueva grandes cuerpos de código a una clase parcial.

Cada plantilla en tiempo de ejecución genera una definición de clase parcial que se llama igual que la plantilla. Puede escribir un archivo de código que contenga otra definición parcial de la misma clase. Así es como se pueden agregar métodos, campos y constructores a la clase. Se puede llamar a estos miembros desde los bloques de código de la plantilla.

Una ventaja de hacerlo así es que el código es más fácil de escribir, ya que IntelliSense está disponible. Además, puede lograr una mejor separación entre la presentación y la lógica subyacente.

Por ejemplo, en MyReportText.tt:

The total is: <#= ComputeTotal() #>

En MyReportText-Methods.cs:

private string ComputeTotal() { ... }

Permita el código personalizado: especifique puntos de extensión.

Considere la posibilidad de generar métodos virtuales en <#+ bloques de características de clase #>. Esto permite usar una sola plantilla en muchos contextos sin tener que modificarla. En lugar de modificar la plantilla, se puede construir una clase derivada que proporcione la lógica adicional mínima. Esta clase puede ser código normal o una plantilla en tiempo de ejecución.

Por ejemplo, en MyStandardRunTimeTemplate.tt:

This page is copyright <#= CompanyName() #>.
<#+ protected virtual string CompanyName() { return ""; } #>

En el código de una aplicación:

class FabrikamTemplate : MyStandardRunTimeTemplate
{
  protected override string CompanyName() { return "Fabrikam"; }
}
...
  string PageToDisplay = new FabrikamTemplate().TextTransform();

Directrices para todas las plantillas T4

Separe la recopilación de datos de la generación de texto.

Intente evitar mezclar bloques de cálculo y texto. En cada plantilla de texto, use el primer <# bloque de código #> para establecer las variables y realizar cálculos complejos. Desde el primer bloque de texto hasta el final de la plantilla o la primera instancia de <#+ bloques de características de clase #>, evite tanto expresiones largas como bucles y condicionales, a menos que contengan bloques de texto. Esta práctica facilita la lectura y mantenimiento de la plantilla.

No use .tt para archivos de inclusión.

Use una extensión de nombre de archivo diferente, como .ttinclude para los archivos de inclusión. Use .tt solo para los archivos que quiera procesar como plantillas de texto en tiempo de ejecución o en tiempo de diseño. En algunos casos, Visual Studio reconoce archivos .tt y establece automáticamente sus propiedades para su procesamiento.

Inicie cada plantilla como un prototipo fijo.

Escriba un ejemplo del código o texto que desea generar y asegúrese de que es correcto. A continuación, cambie su extensión a .tt e inserte incrementalmente código que modifique el contenido leyendo el modelo.

Considere la posibilidad de usar modelos tipados.

Aunque puede crear un esquema XML o de base de datos para los modelos, puede resultar útil crear un lenguaje específico del dominio (DSL). Este lenguaje tiene la ventaja de que genera una clase, que representa cada nodo del esquema, y propiedades, que representan los atributos. Esto significa que puede programar en términos del modelo empresarial. Por ejemplo:

Team Members:
<# foreach (Person p in team.Members)
 { #>
    <#= p.Name #>
<# } #>

Considere la posibilidad de usar diagramas para los modelos.

Muchos modelos se presentan y administran de forma más eficaz simplemente como tablas de texto, especialmente si son muy grandes.

Sin embargo, para algunos tipos de requisitos empresariales, es importante aclarar conjuntos complejos de relaciones y flujos de trabajo, y los diagramas son el medio más adecuado. Una ventaja de un diagrama es que es fácil debatir con usuarios y con otras partes interesadas. Al generar código a partir de un modelo en el nivel de requisitos empresariales, el código se hace más flexible cuando cambian los requisitos.

También puede diseñar su propio tipo de diagrama como un lenguaje específico del dominio (DSL). El código se puede generar a partir de UML y DSL. Para más información, consulte Análisis y modelado de una arquitectura.