Всем привет! Сегодня я хочу рассказать вам о замечательной технологии, которую предоставляет разработчикам Visual Studio – среда разработки шаблонов, известная под кодовым именем Т4.
Наверняка многие из вас сталкивались с такой очень распространенной задачей, как генерация писем. Одним из самых распространенных решений для таких задач являются XSLT трансформации. Вы определяете шаблон письма, включая различные операторы XSLT и затем вызываете специальный генератор, который осуществляет трансформацию, на основе переданных данных для письма. Данная технология отлично работала, и я сам ею пользовался, пока не столкнулся с механизмом Т4.
С помощью Т4 можно с легкостью сделать тоже самое, но при этом получить несколько преимуществ:
- В шаблонах Т4 вы можете с легкостью объявлять и использовать любые операции, доступные в языке C#;
- С легкостью привязывать статический текст шаблонов к ресурсным файлам вашего проекта;
- В процессе компиляции проекта шаблоны будут преобразованы в классы на языке C#, которые будут в свою очередь предварительно скомпилированы, а при выполнении – оптимизированы средой CLR.
Последнее преимущество будет весьма значимо, если для проекта крайне критично время построения шаблона. Скомпилированный класс с набором операций будет по умолчанию выполняться на порядок быстрее, чем любая XSLT трансформация.
Наверняка многие из вас сталкивались с шаблонами Т4, даже не подозревая об этом. Например отображения(View) в ASP.NET MVC работают при помощи шаблонов Т4. Entity Framework версии 4.0 использует этот механизм для автоматической генерации классов по схеме базы данных (правда в этом случае используется немного другой формат работы Т4, но об этом мы подробнее поговорим в другой статье).
Итак, хватит теории, давайте посмотрим как использовать Т4 на практике. Реализуем самый простой механизм генерации писем на основе шаблонов Т4.
Создадим новый проект и добавим туда новый элемент типа Preprocessed Text Template.
Visual Studio 2010 по умолчанию содержит все необходимые компоненты для Т4. Однако, есть один минус – в тексте шаблона отсутствует подсветка синтаксиса C#. Это довольно просто поправить – необходимо установить дополнение для Visual Studio, под названием “Visual T4”. Это очень крутая штука, которая обеспечит вам, не только подсветку синтаксиса, но и полный IntelliSense и валидацию кода.
После добавления элемента в проект, в Solution Explorer появится файл с расширением “.tt” и вложенный в него файл с расширением “.cs”.
Попробуйте открыть оба файла. Файл tt – это собственно наш шаблон, в котором вы можете определять нужную вам разметку письма. Файл cs – это класс-оболочка для шаблона, все команды и текст, который вы определите в шаблоне, будут автоматически преобразованы в последовательность команд на языке C# и записаны в метод TransformText этого файла.
Создадим шаблон, с письмо приветствия для нового пользователя: 1: <#@ template language="C#" #>
2: Welcome to our web-site!
3:
4: <#= DateTime.Now #>
Первая директива указывает на каком языке написан, встроенный в шаблон, код. Во второй строке мы выводим статический текст, а в третей строке выводится текущая дата и время, при помощи кода. Отлично, но неплохо было бы добавить сюда имя пользователя, то есть передать в наш шаблон какой-нибудь параметр.
Это можно сделать сделать двумя способами. Вы, возможно, обратили внимание, что класс-оболочка для шаблона объявлен с модификатором partial. Это значит, что он открыт для расширения и для этого можно не использовать наследование. Давайте расширим этот класс, добавив туда нужную нам переменную:
1: partial class MessageTemplate
2: {
3: public string UserName { get; set; }
4: }
1: <#@ template language="C#" #>
2:
3: Hello, <#= this.UserName #>
4: Welcome to our web-site!
5: <#= DateTime.Now #>
Это – первый способ передачи параметров в шаблон. Чтобы узнать о втором способе, необходимо сначала научиться вызывать наши шаблоны. Для этого мы используем простое консольное приложение:
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: var messageTmpl = new MessageTemplate();
6: messageTmpl.UserName = "Jack Daniels";
7: string message = messageTmpl.TransformText();
8:
9: Console.WriteLine(message);
10: }
11: }
Мы создали новый объект класса-оболочки шаблона и установили параметр, который мы ранее внедрили через partial класс. Далее, вызвав метод TransformText, мы получили готовое письмо с подставленными данными. Результат на окне консоли будет предсказуем:
Второй способ передачи параметров предполагает передачу параметров в формате ключ-значение. Изменим способ вызова шаблона, передав параметр через словарь (не забудьте удалить partial класс, в противном случае будет конфликт имен).
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: var messageTmpl = new MessageTemplate();
6:
7: messageTmpl.Session = new Dictionary<string, object>();
8: messageTmpl.Session.Add("UserName", "Jack Daniels");
9: messageTmpl.Initialize();
10:
11: string message = messageTmpl.TransformText();
12:
13: Console.WriteLine(message);
14: }
15: }
Параметры записываются в словарь Session, который есть у каждого шаблона. Нужно отметить, что поле Session по умолчанию равно null и в случае передачи параметров таким способом, необходимо вызвать метод Initialize, иначе параметры переданы в шаблон не будут.
Сам шаблон также нужно модифицировать:1: <#@ template language="C#" #>
2: <#@ Parameter Name="UserName" Type="System.String" #>
3:
4: Hello, <#= this.UserName #>
5:
6: Welcome to our web-site!
7:
8: <#= DateTime.Now #>
Каждый параметр, необходимо задекларировать, указав его имя и тип.
Как вы могли заметить первый способ, который предполагает создание partial класса, явно более удобен и легок в использовании, требует намного меньшего объема кода, а также является более красивым походом с точки зрения архитектуры приложения.
В этой статье был предоставлен краткий обзор шаблонов Т4 и был приведен пример реализации самой простой задачи при помощи этого механизма. Однако, возможности Т4 уходят далеко за рамки таких простых сценариев. Различные особенности и приемы, которые можно использовать в Т4 будут рассмотрены в следующей статье.
Комментариев нет:
Отправить комментарий