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”
Prosty template T4
Dla prostej prezentacji stworzyłem prostą aplikację konsolową. Chociaż szczerze to może być jakikolwiek inny projekt
Do projektu do dodajemy pliki z “tangible T4 Editor”. Plik ten ma rozszerzenie “.tt”.
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”.
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.
Możesz także wybrać język, w którym będziesz pisał kod, który wygeneruję ci klasę lub coś innego.
Linijka “output” określa rozszerzenie wygenerowanego pliku, jak i jego format kodowania.
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.
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”.
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.
Jak widać breakpoint przy wyrażeniu “readline()” nie działa, bo jest to zwykły tekst.
Składnia T4
Jak 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.
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.
Tag | Co 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.