Bloques de control de plantilla de texto

Los bloques de control permiten escribir código en la plantilla de texto para variar la salida. Hay tres tipos de bloques de control, que se distinguen por sus corchetes de apertura:

  • <# Standard control blocks #> puede contener declaraciones.

  • <#= Expression control blocks #> puede contener expresiones.

  • <#+ Class feature control blocks #> puede contener métodos, campos y propiedades.

Bloque de control estándar

Los bloques de control estándar contienen instrucciones. Por ejemplo, el siguiente bloque estándar obtiene los nombres de todos los atributos del documento XML:

<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System.Xml" #>

<#
    List<string> allAttributes = new List<string>();
    XmlDocument xDoc = new XmlDocument();
    xDoc.Load(@"E:\CSharp\Overview.xml");
    XmlAttributeCollection attributes = xDoc.Attributes;
    if (attributes.Count > 0)
    {
       foreach (XmlAttribute attr in attributes)
       {
           allAtributes.Add(attr.Name);
       }
     }
#>

Puede insertar texto sin formato dentro de una instrucción compuesta como if o for. Por ejemplo, este fragmento genera una línea de salida en cada iteración de bucle:

<#
       foreach (XmlAttribute attr in attributes)
       {
#>
Found another one!
<#
           allAtributes.Add(attr.Name);
       }
#>

Advertencia

Use siempre {...} para delimitar instrucciones anidadas que contienen texto sin formato incrustado. Es posible que el ejemplo siguiente no funcione correctamente:

<# if (ShouldPrint) #> Some text. -- WRONG

En su lugar, debe incluir {corchetes}, como se indica a continuación:


<#
 if (ShouldPrint)
 {   //  "{" REQUIRED
#>
Some text.
<#
 }
#>

Bloque de control de expresiones

Los bloques de control de expresiones se usan para el código que proporciona cadenas que se van a escribir en el archivo de salida. Por ejemplo, con el ejemplo anterior, puede imprimir los nombres de los atributos en el archivo de salida modificando el bloque de código de la siguiente manera:

<#
    XmlDocument xDoc = new XmlDocument();
    xDoc.Load(@"E:\CSharp\Overview.xml");
    XmlAttributeCollection attributes = xDoc.Attributes;
    if (attributes != null)
    {
       foreach (XmlAttribute attr in attributes)
       {
#><#= attr.Name #><#
       }
    }
#>

Bloque de control de funciones de clase

Puede usar bloques de control de características de clase para agregar métodos, propiedades, campos o incluso clases anidadas a la plantilla de texto. El uso más común de los bloques de características de clase es proporcionar funciones auxiliares para código en otras partes de la plantilla de texto. Por ejemplo, el bloque de características de clase siguiente capitaliza la primera letra del nombre del atributo (o, si el nombre contiene espacios en blanco, capitaliza la primera letra de cada palabra):

<#@ import namespace="System.Globalization" #>
<#+
    private string FixAttributeName(string name)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name);
    }
#>

Nota:

Un bloque de control de características de clase no debe ir seguido de bloques de control estándar en el mismo archivo de plantilla. Sin embargo, esta restricción no se aplica al resultado de las directivas using <#@include#> . Cada archivo incluido puede tener bloques estándar seguidos de bloques de características de clase.

Puede crear una función que genere la salida insertando bloques de texto y expresión dentro de un bloque de control de características de clase. Por ejemplo:

<#+
    private void OutputFixedAttributeName(string name)
    {
#>
 Attribute:  <#= CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name) #>
<#+  // <<< Notice that this is also a class feature block.
    }
#>

Puede llamar a esta función desde un bloque estándar o desde otro bloque de características de clase:

<# foreach (Attribute attribute in item.Attributes)
{
  OutputFixedAttributeName(attribute.Name);
}
#>

Cómo usar bloques de control

Todo el código de todos los bloques de control estándar y de expresión de una sola plantilla (incluido todo el código de las plantillas incluidas) se combina para formar el TransformText() método del código generado. (Para obtener más información sobre cómo incluir otras plantillas de texto con la include directiva , vea Directivas de plantilla de texto T4).

Debe tener en cuenta las siguientes consideraciones al usar bloques de control:

  • Idioma. Puede usar código de C# o Visual Basic en una plantilla de texto. El lenguaje predeterminado es C#, pero puede especificar Visual Basic con el parámetro language de la directiva template. (Para obtener más información sobre la template directiva, vea Directivas de plantilla de texto T4).

    El idioma que se usa en los bloques de control no tiene nada que ver con el idioma o el formato del texto que se genera en una plantilla de texto. Puede generar C# mediante código de Visual Basic o viceversa.

    Solo puede usar un idioma en una plantilla de texto determinada, incluidas todas las plantillas de texto que incluya con la include directiva .

  • Variables locales. Dado que todo el código de los bloques de control estándar y de expresión de una plantilla de texto se genera como un único método, debe asegurarse de que no haya conflictos con los nombres de las variables locales. Si incluye otras plantillas de texto, debe asegurarse de que los nombres de variable sean únicos en todas las plantillas incluidas. Una manera de asegurarse de que esto es agregar una cadena a cada nombre de variable local que identifique la plantilla de texto en la que se declaró.

    También es recomendable inicializar las variables locales en valores razonables al declararlas, especialmente cuando se incluyen varias plantillas de texto.

  • Anidamiento de bloques de control. Los bloques de control no pueden anidarse entre sí. Siempre debe finalizar un bloque de control determinado antes de abrir otro. Por ejemplo, a continuación se muestra cómo imprimir texto en un bloque de expresión como parte de un bloque de control estándar.

    <#
    int x = 10;
    while (x-- > 0)
    {
    #>
    <#= x #>
    <# } #>
    
  • Refactorización. Para mantener las plantillas de texto cortas y fáciles de entender, se recomienda encarecidamente evitar código repetitivo mediante la factorización del código reutilizable en funciones auxiliares en bloques de características de clase o mediante la creación de su propia clase de plantilla de texto que hereda de la clase Microsoft.VisualStudio.TextTemplating.TextTransformation.