T4 Ten artykuł demonstruje jak łatwo stworzyć prosty schemat T4, który wygeneruje kod w C# bez bawienia się w bardziej zaawansowane narzędzia jak DLS.

Jeśli nie wiesz co to jest T4 i jak tego użyć spokojnie ten wpis pokaże wszystko co musisz wiedzieć aby zacząć swoją przygodę.

T4 jest częściowo jest wspierane przez Visual Studio 2012.Visual Studio zawiera darmowy debugger T4.

By mieć mało stresujący początek warto zainstalować dodatek “t4 editor” w darmowej wersji. Oferuje on gotowe schematy plików, które znajdują w zakładce “tangible T4 Editor”

image

Prosty template T4

Dla prostej prezentacji stworzyłem prostą aplikację konsolową. Chociaż szczerze to może być jakikolwiek inny projekt Uśmiech

T4

Do projektu do dodajemy pliki z “tangible T4 Editor”. Plik ten ma rozszerzenie “.tt”.

T4 add item

Twoim oczom powinien ukazać następująca zawartość. Chociaż może być ona różna w zależności od typu projektu, w jakim pracujemy. Na przykład odwołanie do biblioteki “System.Windows.Forms” wiadomo nie wystąpi wszędzie.

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="System.Core" #>
<#@ Assembly Name="System.Windows.Forms" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #> 
<#


#>

Na razie jednak powinieneś zwróci uwagę tylko na te dwie linijki.

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#


#>

W linijce “template” mamy zadeklarowane dwa atrybuty. Co one oznaczają?

Atrybut “hostSpecific” określa czy dany “template” korzysta z domyślnego silnika kompilacyjnego, który jest wbudowany w Visual Studio. Jeśli plik .tt ma być używany w innych narzędziach niż Visual Studio wtedy ten atrybut określamy na “false”.

hostSpecific

Atrybut “debug” określa czy dany “template” może być sprawdzany. Jest to zupełnie odlotowa i nowa opcja, gdyż schematy T4 istniały od wielu lat ,ale nie można było sprawdzać ich poprawności.

debug

Możesz także wybrać język, w którym będziesz pisał kod, który wygeneruję ci klasę lub coś innego.

image

Linijka “output” określa rozszerzenie wygenerowanego pliku, jak i jego format kodowania.

image

Wygenerowanie klasy

Oto prosty kod T4, który wygeneruje klasę.

<#@ template language="C#" hostSpecific="true" debug="true"  #>
<#@ output extension=".cs"   #>
<#
    string ClassName = "MyClass";
    string MethodName = "Hello ";

#>
// <autogenerated>
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// </autogenerated>
using System;
   
namespace T4Console
{
    public class <#= ClassName #>
    {
       public static void <#=  MethodName #>()
       {
          Console.WriteLine("<#=  MethodName + ClassName #>");
          Console.ReadLine();
       }
    }
}

Widać tutaj wyraźny podział.Ten kod deklaruje zmienne i przypisuje im wartości.

<#
    string ClassName = "MyClass";
    string MethodName = "Hello ";

#>

A ten kod używa wcześniej przypisany zmiennych. Pomimo koloryzacji Visual Studio wszystko co nie jest oznacza w tagach “<#”,”<#=” jest zwykłym tekstem. Ten tekst zostanie dołączonym do pliku.

// <autogenerated>
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// </autogenerated>
using System;
   
namespace T4Console
{
    public class <#= ClassName #>
    {
       public static void <#=  MethodName #>()
       {
          Console.WriteLine("<#=  MethodName + ClassName #>");
          Console.ReadLine();
       }
    }
}

Wygenerowana klasa znajduje się pod plikiem .tt.

image

Wygenerowana klasa wygląda tak.

// <autogenerated>
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// </autogenerated>
using System;
   
namespace T4Console
{
    public class MyClass
    {
       public static void Hello ()
       {
          Console.WriteLine("Hello MyClass");
          Console.ReadLine();
       }
    }
}

Prawda ,że było to proste.

Teraz wyobraź ,że za pomocą pewnych informacji w bazie danych bądź w pliku XML tworzysz swoją klasę dynamicznie.

Debugowanie

Jeśli chcesz sprawdzić poprawność działania swojego kodu T4 wystarczy z menu kontekstowego wybrać “Debug T4 Template”.

image

Co do debugowania “template-u” warto pamiętać o tym ,że sprawdzamy w ten sposób działanie generatora ,a nie działanie naszej wyplutej klasy.

imageimage

Jak widać breakpoint przy wyrażeniu “readline()” nie działa, bo jest to zwykły tekst.

Składnia T4

imageJak widziałeś do wygenerowania klasy używałem dwóch tagów. W tagu “<#” zadeklarowałem zmienne ,a w tagu “<#=”wydrukowałem ich zawartość w odpowiednich miejscach.

Tag “<#@”jest używany do określenia meta informacji na temat danego schematu. Te meta informacje określają użyte przestrzenie nazw, biblioteki i tak dalej.

Do dyspozycji mamy jeszcze jeden tag. <#+

<#+   // Start of class feature block
private int Square(int i)
{
    return i*i;
}
#>

W tym tagu deklarujemy metodę, która może być później użyta w tagach <# , <#+.

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension="txt" #>
Squares:
<#
    for(int i = 0; i < Square(2); i++)
    {
#>
    The square of <#= i #> is <#= Square(i+1) #>.
<#
    } 
#>

<#+   // Start of class feature block
private int Square(int i)
{
    return i*i;
}
#>

Powyższy kod stworzy następujący plik tekstowy.

image

Squares:
    The square of 0 is 1.
    The square of 1 is 4.
    The square of 2 is 9.
    The square of 3 is 16.

Podsumowując o to co trzeba pamiętać o tagach w pliku T4.

TagCo to jest?
<#@Meta dane o danym pliku “.tt”
<#Kod, który zostanie normalnie skompilowany
<#=Kod wydrukuje zawartość zmiennych jako string.
<#+Deklaracja metod,klas do przyszłego użycia

 

To wszystko co musisz wiedzieć aby zacząć swoją przygodę z T4 w Visual Studio 2012.