Написание текстового шаблона T4
Текстовый шаблон содержит текст, который будет создан на его основе. Например, шаблон, создающий веб-страницу, будет содержать html<>..." и все остальные стандартные части HTML-страницы. Вставленными в шаблон являются блоки управления, которые являются фрагментами кода программы. Блоки управления обеспечивают варьирующиеся значения и обеспечивают условность и повторяемость текста.
Эта структура упрощает разработку шаблона, так как можно начать с прототипа созданного файла и постепенно вставлять блоки управления, которые будут обеспечивать изменение результата.
Текстовые шаблоны состоят из следующих частей.
Директивы — элементы, управляющие обработкой шаблона.
Текстовые блоки — содержимое, скопированное непосредственно в выходные данные.
Блоки управления — программный код, который вставляет значения переменных в текст и управляет условными или повторяющимися частями текста.
Чтобы попробовать примеры в этом разделе, скопируйте их в файл шаблона, как описано в разделе "Создание кода во время разработки" с помощью шаблонов текста T4. После редактирования файла шаблона сохраните его, а затем проверьте выходной TXT-файл .
Директивы
Директивы текстовых шаблонов предоставляют общие инструкции модулю текстовых шаблонов в отношении порядка создания кода преобразования и выходного файла.
Например, следующая директива указывает, что выходной файл должен иметь расширение .TXT.
<#@ output extension=".txt" #>
Дополнительные сведения об директивах см. в директивах шаблонов T4.
Текстовые блоки
Текстовый блок вставляет текст непосредственно в выходной файл. Для текстовых блоков нет особых правил форматирования. Например, следующий текстовый шаблон создаст текстовый файл со словом "Hello":
<#@ output extension=".txt" #>
Hello
Блоки управления
Блоки управления — это части программного кода, которые используются для преобразования шаблонов. Язык по умолчанию — C#, но для использования Visual Basic можно написать эту директиву в начале файла:
<#@ template language="VB" #>
Язык, на котором вы будете писать код в блоках управления, не связан с языком создаваемого текста.
Стандартные блоки управления
Стандартный блок управления представляет собой раздел программного кода, который создает часть выходного файла.
В файле шаблона можно смешивать любое число блоков текста и стандартных блоков управления. При этом нельзя помещать один блок управления в другой. Каждый стандартный блок управления отделяется символами <# ... #>
.
Например, следующий блок управления и текстовый блок создают выходной файл, который содержит строку "0, 1, 2, 3, 4 Hello!":
<#
for(int i = 0; i < 4; i++)
{
Write(i + ", ");
}
Write("4");
#> Hello!
Вместо использования явных операторов Write()
, можно чередовать текст и код. В следующем примере печатается "Hello!" четыре раза:
<#
for(int i = 0; i < 4; i++)
{
#>
Hello!
<#
}
#>
Можно вставить блок текста в любое место кода, где допускается вставка оператора Write();
.
Примечание.
При внедрении текстового блока в составную инструкцию, например цикл или условный, всегда используйте фигурные скобки {...} для хранения текстового блока.
Блоки управления выражениями
Блок управления выражением оценивает выражение и преобразует его в строку, которая вставляется в выходной файл.
Блоки управления выражениями разделяются символами <#= ... #>
Например, следующий блок управления задает, что выходной файл будет содержать "5":
<#= 2 + 3 #>
Обратите внимание, что открывающий символ имеет три символа "<#=".
Это выражение может включать любую переменную в области. Например, этот блок печатает строки цифр:
<#@ output extension=".txt" #>
<#
for(int i = 0; i < 4; i++)
{
#>
This is hello number <#= i+1 #>: Hello!
<#
}
#>
Блоки управления возможностями класса
Блок управления возможностями класса определяет свойства, методы или другой код, который не должен включаться в основное преобразование. Блоки возможностей класса часто используются для написания возможностей вспомогательных приложений. Как правило, блоки функций класса помещаются в отдельные файлы, чтобы они могли быть включены в несколько текстовых шаблонов.
Блоки управления возможностями класса разделяются символами <#+ ... #>
.
Например, следующий файл шаблона объявляет и использует метод:
<#@ output extension=".txt" #>
Squares:
<#
for(int i = 0; i < 4; i++)
{
#>
The square of <#= i #> is <#= Square(i+1) #>.
<#
}
#>
That is the end of the list.
<#+ // Start of class feature block
private int Square(int i)
{
return i*i;
}
#>
Возможности класса необходимо помещать в конец файла, в котором они написаны. Однако можно включить файл (используя <#@include#>
), содержащий возможность класса, даже если за директивой include
следует текст и стандартные блоки.
Дополнительные сведения о блоках управления см. в разделе "Блоки элементов управления текстовым шаблоном".
Блоки возможностей класса могут содержать текстовые блоки
Вы можете написать метод, создающий текст. Например:
List of Squares:
<#
for(int i = 0; i < 4; i++)
{ WriteSquareLine(i); }
#>
End of list.
<#+ // Class feature block
private void WriteSquareLine(int i)
{
#>
The square of <#= i #> is <#= i*i #>.
<#+
}
#>
Особенно полезным будет поместить метод, создающий текст, в отдельный файл, который можно будет включить в несколько шаблонов.
Использование внешних определений
Сборки
Блоки кода шаблона могут использовать типы, определенные в наиболее часто используемых сборках .NET, таких как System.dll. Кроме того, можно добавить ссылку на другие сборки .NET или ваши собственные. Можно предоставить путь или строгое имя сборки:
<#@ assembly name="System.Xml" #>
Необходимо использовать абсолютные пути или стандартные имена макросов в пути. Например:
<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>
Директива сборки не действует в предварительно обработанном текстовом шаблоне.
Дополнительные сведения см. в директиве T4 Assembly.
Пространства имен
Директива import соответствует выражению using
в C# или выражению imports
в Visual Basic. Она позволяет ссылаться на типы в коде, не используя полное имя:
<#@ import namespace="System.Xml" #>
Число используемых директив assembly
и import
не ограничено. Их нужно размещать до блоков управления и текста.
Дополнительные сведения см. в директиве импорта T4.
Включение кода и текста
Директива include
вставляет текст из другого файла шаблона. Например, эта директива вставляет содержимое файла test.txt
:
<#@ include file="c:\test.txt" #>
Включенное содержимое обрабатывается почти так же, как если бы оно было частью включающего текстового шаблона. При этом можно включить файл, содержащий блок возможностей класса <#+...#>
, даже если за директивой include следуют обычный текст и стандартные блоки управления.
Дополнительные сведения см. в директиве T4 Include.
Служебные методы
Существует несколько методов, таких как Write()
, которые всегда можно использовать в блоке управления. Они включают методы, помогающие создать отступы для вывода или отчеты об ошибках.
Кроме того, вы можете создать собственный набор служебных методов.
Дополнительные сведения см. в разделе "Методы служебной программы текстового шаблона".
Преобразование данных и моделей
Наиболее полезная сфера применения текстовых шаблонов — создание материалов на основе содержимого источника, такого как модель, база данных или файл данных. Шаблон извлекает данные и изменяет их формат. Коллекция шаблонов может преобразовать подобный источник в несколько файлов.
Существует несколько способов считывания исходного файла.
Чтение файла в текстовом шаблоне. Это самый простой способ получения данных в шаблоне:
<#@ import namespace="System.IO" #>
<# string fileContent = File.ReadAllText(@"C:\myData.txt"); ...
Загрузите файл в виде навигации модели. Более эффективный способ — это чтение данных как модели, по которой может перемещаться код текстового шаблона. Например, можно загрузить XML-файл и выполнять навигацию по этому файлу с помощью выражений XPath. Можно также использовать xsd.exe для создания набора классов, с помощью которых можно считывать XML-данные.
Измените файл модели в схеме или форме. Инструменты языка для конкретного домена предоставляют средства, позволяющие изменять модель в виде схемы или формы Windows. Это упрощает обсуждение модели с пользователями созданного приложения. Инструменты языка для конкретного домена также создают набор строго типизированных классов, которые отражают структуру модели. Дополнительные сведения см. в разделе "Создание кода на языке для конкретного домена".
Относительные пути файлов в шаблонах времени разработки
В текстовом шаблоне времени разработки, если вы хотите ссылаться на файл в расположении относительно текстового шаблона, используйте this.Host.ResolvePath()
. Кроме того, необходимо задать выражение hostspecific="true"
в директиве template
:
<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="System.IO" #>
<#
// Find a path within the same project as the text template:
string myFile = File.ReadAllText(this.Host.ResolvePath("MyFile.txt"));
#>
Content of MyFile.txt is:
<#= myFile #>
Можно также получить другие службы, предоставляемые узлом. Дополнительные сведения см. в разделе "Доступ к Visual Studio" или другим узлам из шаблона.
Текстовые шаблоны времени разработки выполняются в отдельном домене приложения
Следует учитывать, что текстовый шаблон во время разработки выполняется в домене приложения, отдельном от основного приложения. В большинстве случаев это неважно, однако вы можете столкнуться с ограничениями в некоторых сложных случаях. Например, если нужно передать данные в шаблон или из него, используя отдельную службу, эта служба должна предоставить сериализуемый API.
(Это не верно в текстовом шаблоне времени выполнения, который предоставляет код, скомпилированный вместе с остальным кодом.)
Редактирование шаблонов
Специализированные редакторы текстовых шаблонов можно загрузить из каталога диспетчера расширений в Интернете. В меню "Сервис" щелкните "Диспетчер расширений". Щелкните онлайн-коллекцию и используйте средство поиска.