Blocos de controle do modelo de texto
Os blocos de controle permitem que você escreva código em seu modelo de texto para variar a saída. Há três tipos de blocos de controle, que são diferenciados por seus colchetes de abertura:
<# Standard control blocks #>
pode conter instruções.<#= Expression control blocks #>
pode conter expressões.<#+ Class feature control blocks #>
pode conter métodos, campos e propriedades.
Bloco de controle padrão
Os blocos de controle padrão contêm instruções. Por exemplo, o seguinte bloco padrão obtém os nomes de todos os atributos no 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);
}
}
#>
Você pode inserir texto sem formatação dentro de uma instrução composta, como if
ou for
. Por exemplo, esse fragmento gera uma linha de saída em cada iteração de loop:
<#
foreach (XmlAttribute attr in attributes)
{
#>
Found another one!
<#
allAtributes.Add(attr.Name);
}
#>
Aviso
Sempre use {...} para delimitar instruções aninhadas contendo texto sem formatação inserido. O exemplo a seguir pode não funcionar corretamente:
<# if (ShouldPrint) #> Some text. -- WRONG
Em vez disso, você deve incluir {chaves}, da seguinte maneira:
<#
if (ShouldPrint)
{ // "{" REQUIRED
#>
Some text.
<#
}
#>
Bloco de controle de expressão
Os blocos de controle de expressão são usados no código que fornece cadeias de caracteres a serem gravadas no arquivo de saída. Por exemplo, com o exemplo acima, você pode imprimir os nomes dos atributos no arquivo de saída modificando o bloco de código da seguinte maneira:
<#
XmlDocument xDoc = new XmlDocument();
xDoc.Load(@"E:\CSharp\Overview.xml");
XmlAttributeCollection attributes = xDoc.Attributes;
if (attributes != null)
{
foreach (XmlAttribute attr in attributes)
{
#><#= attr.Name #><#
}
}
#>
Bloco de controle de recurso de classe
Você pode usar blocos de controle de recurso de classe para adicionar métodos, propriedades, campos ou até mesmo classes aninhadas a seu modelo de texto. O uso mais comum dos blocos de recurso de classe é fornecer funções auxiliares para o código em outras partes do modelo de texto. Por exemplo, o bloco de recursos de classe a seguir muda para maiúscula a primeira letra do nome do atributo (ou, se o nome contiver espaço em branco, ele muda para maiúscula a primeira letra de cada palavra):
<#@ import namespace="System.Globalization" #>
<#+
private string FixAttributeName(string name)
{
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name);
}
#>
Observação
O bloco de controle de recurso de classe não deve vir seguido por blocos de controle padrão no mesmo arquivo de modelo. No entanto, essa restrição não se aplica ao resultado do uso de diretivas <#@include#>
. Cada arquivo incluído pode ter blocos padrão seguidos por blocos de recurso de classe.
Você pode criar uma função que gera a saída inserindo blocos de texto e expressão dentro de um bloco de controle de recurso de classe. Por exemplo:
<#+
private void OutputFixedAttributeName(string name)
{
#>
Attribute: <#= CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name) #>
<#+ // <<< Notice that this is also a class feature block.
}
#>
Você pode chamar essa função a partir de um bloco padrão ou de outro bloco de recurso de classe:
<# foreach (Attribute attribute in item.Attributes)
{
OutputFixedAttributeName(attribute.Name);
}
#>
Como usar blocos de controle
Todo o código em todos os blocos de controle padrão e de expressão em um único modelo (incluindo todo o código nos modelos incluídos) é combinado para formar o método TransformText()
do código gerado. (Para obter mais informações sobre como incluir outros modelos de texto com a diretiva include
, consulte Diretivas de modelo de texto T4.)
Você deve ter em mente as seguintes considerações ao usar blocos de controle:
Idioma. Você pode usar o código C# ou Visual Basic em um modelo de texto. A linguagem padrão é C#, mas você pode especificar o Visual Basic com o parâmetro
language
da diretivatemplate
. (Para saber mais sobre a diretivatemplate
, consulte as Diretivas do modelo de texto T4.)A linguagem que você usa nos blocos de controle não tem nada a ver com a linguagem ou formato do texto gerado em um modelo de texto. Você pode gerar C# usando o código do Visual Basic ou vice-versa.
Você pode usar apenas uma linguagem em um determinado modelo de texto, incluindo todos os modelos de texto incluídos com a diretiva
include
.Variáveis locais. Como todo o código nos blocos de controle padrão e de expressão em um modelo de texto é gerado como um único método, você deve certificar-se de que não há conflitos com os nomes das variáveis locais. Se você estiver incluindo outros modelos de texto, deverá garantir que os nomes das variáveis sejam exclusivos em todos os modelos incluídos. Uma maneira de garantir isso é adicionar uma cadeia de caracteres a cada nome de variável local que identifica o modelo de texto no qual ele foi declarado.
Também é uma boa ideia inicializar suas variáveis locais com valores sensatos quando você as declara, especialmente quando você está incluindo vários modelos de texto.
Aninhamento de blocos de controle. Os blocos de controle podem não estar aninhados entre si. Você sempre deve encerrar um determinado bloco de controle antes de abrir outro. O exemplo abaixo mostra como imprimir algum texto em um bloco de expressão como parte de um bloco de controle padrão.
<# int x = 10; while (x-- > 0) { #> <#= x #> <# } #>
Refatoração. Para manter seus modelos de texto curtos e fáceis de entender, é altamente recomendável evitar o código repetitivo, ou considerando o código reutilizável em funções auxiliares em blocos de recurso de classe ou criando sua própria classe de modelo de texto herdada da classe Microsoft.VisualStudio.TextTemplating.TextTransformation.