Страницы

Поиск по вопросам

пятница, 19 октября 2018 г.

В чем смысл текстовых шаблонов T4 и когда их имеет смысл использовать?

В чем смысл текстовых шаблонов T4? По сути, этого же можно добиться с помощью динамической компиляции. Доступ к исходному коду так же не даёт никаких преимуществ, так как править его не имеет смысла из за перегенерации.


Ответ

Если вы имеете в виду T4, то их смысл — встроенный в систему шаблонизатор/DSL. T4 используется в двух вариантах: времени компиляции и времени выполнения.
T4 времени выполнения обычно используется как шаблонизатор, и означает, что вы можете легко генерировать текстовые файлы, в которых большая часть текста постоянна, а куски необходимо генерировать программно. Простой пример — шаблон письма, в который нужно вставить имя адресата, адрес и наименование товара.
Но гораздо более интересным является T4 времени разработки. Эта штука позволяет вам генерировать код на этапе компиляции (точнее, даже до неё). То есть, у вас появляется ещё одно прекрасное (хотя и немного неуклюжее — если не сравнивать с шаблонной магией Александреску) средство для настоящего метапрограммирования. Причём в отличие от решений, которые вы могли бы соорудить на коленке, T4 встроен в Visual Studio, и сгенерированные файлы просто видны в дереве Solution Explorer'а, и подхватываются компилятором.
T4 используется для кодогенерации многими проектами, начиная с Entity Framework. Вот здесь ещё достаточно впечатляющий список. Вот, например, пример того, как автоматически генерировать определения Dependency Property. (Я тоже использовал T4 для генерации из текстового представления XAML-словарей для локализации.)

Кодогенерация времени выполнения и правда не лучший метод использования T4. Для этих целей лучше подходит CodeDOM (или, кажется, Roslyn API). А для кодогенерации времени компиляции доступ к сгенерированным исходникам очень важен, например, для отладки.

Дополнение к вопросу из комментария. Да, можно в шаблоне генерировать другой шаблон.
Например, такой вот шаблон
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".tt" #>
<# string open = "<" + "#" + "@", close = "#" + ">"; #>
<#= open #> template debug="false" hostspecific="false" language="C#" <#= close #> <#= open #> assembly name="System.Core" <#= close #> <#= open #> import namespace="System.Linq" <#= close #> <#= open #> import namespace="System.Text" <#= close #> <#= open #> import namespace="System.Collections.Generic" <#= close #> <#= open #> output extension=".cs" <#= close #>
class Test { public int i; }
порождает подчинённый шаблон
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #>
class Test { public int i; }
который в свою очередь порождает класс
class Test { public int i; }
Никаких специальных действий выполнять не нужно, просто добавьте шаблон T4 через Add → New item → Text Template (не Runtime Text Template!)

В T4-файл положите текст шаблона, как он представлен выше, и вы получите такую вот необычную структуру вашего solution'а:

Комментариев нет:

Отправить комментарий