DBMaker - New Technology
New Technology

T4 text templates and application

Author/Chen Xinyang      [Issue Date: 2016/3/4]

Preface

Writing program code for a programmer is a common thing. The routine is to turn on the computer, start the software development tool, and then convert specifications into lines of code that are input to the screen. Sometimes this process involves adjusting the old code to remove errors and meet new customer requirements, however, other times programmers are faced with new systems, new structures and new program code. Of course, for a skilled programmer, writing a program is not difficult, especially these days because of improvements to the efficiency of developing programs and given unified program architectures and procedures. We usually refer to earlier program code and already written standard code pieces which can be used by any developer as a base for the construction of a new system. In this way, not only is the development time reduced, but also the developer can save a lot of unnecessary work when maintaining this code in the future, because much code is similar. Do you also think it is unnecessary to write the same codes day after day, copy the architecture of the base and then adjust different sectors according to the corresponding specifications?

Have you ever imagined that, now that the program codes are very similar and are done in accordance with fixed rules, why not let programs themselves help us do the monotonous work? I believe that many people must have written small tools to assist in developing just such things, like file conversion, generating test data, and more. Therefore, how can we be in this situation where we lack this automatic generation tool?

"Figure I" MSDN Instructions on T4 Text Templates

This article will introduce the T4 template tool provided by Microsoft. It allows you to define program code samples and logic, and generates line by line the program code thus achieving the automatic generation we are discussing. Later when some architecture requires adjustment, one merely adjusts the original T4 template to automatically re-generate all the new code thereby enormously improving the efficiency of program development.

Working Mode and Projects Establishment of T4 Templates

T4, whose full name is Text Template Transformation ToolkitT4 (hereafter called T4 Templates), is composed of text blocks and control logic. You needn't regard T4 Templates as a new language. To write a complete T4 Template, you just need to know C# or Visual Basic, of course the program code produced isn't limit to these languages so you can consider it a text generator containing a great amount of logic and one that is usually used for program code having similar rules.

"Figure II" a brief sample of T4 Text Templates

Figure II simply shows the text block and control logic in T4 Templates, from which it can be seen that whether text blocks or control logical is actually similar to those program code that are typically written.

In the past, before T4 Templates, to write a program to generate other program code or text files, the simplest way was to directly handle categories by character strings like StringBuilder and then to adjust output content in accordance with some logical judgments. Although this writing style is very intuitive, the program code would be difficult to read, especially when adjusting the layout of the output files, because special characters, the line break character for example, behaves differently in code from what we see with our own eyes.

The principle of T4 Templates is actually to provide a way of writing easier to read program code and then to provide an internal conversion to produce the program code illustrated by the following figure.

"Figure III" the second brief sample of T4 Text Templates

The T4 Template is not an independent project. As described early, it is in fact similar to a conversion program. When you write program code with T4 Templates, the system automatically converts these templates into another program and f ultimately uses that program to produce text files. Therefore, you won't see options like T4 Templates when setting up a project. What you need to do is to directly set up a new C# program or a Visual Basic program and then add a new project to this program. Here you can see a option named "text templates of operation time" which generates text files with extensions .tt, .cs or .vb. In "Add new projects," you may notice that there is an option named "text templates" whose extension name also is .tt. The two options are used together for generating text files, but they are used at different times and as well have different processing methods. As described early, when using the "text templates of operation time," the program designer is responsible for writing compositions of the .tt template, and then the complier converts the .tt template into a .cs file and ultimately the file that we want is generated form this .cs file; however, when the "text templates", also known as "text templates of design time" is used, the second step — namely the conversion into .cs files — is absent. This is because "text templates" itself is used to produce the result.

The "text templates of design time" is usually used to automatically update program code, as the program code will adjust accordingly if the data in a database is updated, because a text template will be directly bound with an output file. While the "text templates of operation time" is usually used to generate large numbers of other program code to produce corresponding output for various input data, for example, the different result is due to different design file specifications. Here we take the "text templates of operation time" as an introduction and example.

"Figure IV" Add a T4 Text Template

"Figure V" A .cs file is contained in the T4 Text Template in the operation phase

Before writing a T4 template, we usually create a partial class for this file. As mentioned, usually there are output files like documents, therefore, the partial class is created for us to record the information this file needs, for example, automatically produce web pages, you might need to define the name of a web page and the data and function of a field, therefore another program will move the information into this object for use later.

Text Blocks and Control Logic

After all files are created, it's time to write the T4 templates. The final program code is produced by T4 text templates, therefore the final program code and text files must not be checked by the complier, of course we cannot be sure whether they will run. If a certain control logic of a T4 template is too complex, it usually makes this program difficult to read, accordingly, it is a rather difficult to adjust later on. To avoid constant adjustment to T4 templates files and at the same time reduce the possibility that this program cannot be edited, we usually complete the first program by hand, copy and paste it into a T4 template after we make sure it runs normally, and then adjust it later line by line. In this way, we make sure that the program's architecture is correct. In addition, the modification will be minor when there is a need for it in the future.

The following T4 template example generates a web page. This web page consists of front-end aspx and back-end aspx.cs, and maintains basic database files, including: selecting, inserting, updating, and deleting. The onscreen query window, result, and details program code are not describe herein. The practice and concept are very similar, therefore here we show a example when introduce the T4 template, which provides a convenient tool for us to understand its usage.

After having produced a T4 template in accordance with the previous section, you will see some program code generated at the beginning in this file, including the language defining the template. The language here is the program code of control logic in this T4 template rather than the generated codes. By default, it has an identical type as that of your project by default. Modifications are possible, for example, if we set the template language to VB, the associated .cs file would also change to the .vb file, which also means the syntax used in this template would be VB.

The above program code was used to illustrate how to write a T4 template.I It’s the code used to define the backend part in the front-end program code of a .NET web page. We want to make this part contained in the program code of every web program, therefore we will save the program code of this part in the T4 template. However, this part would be different in different programs for we need to define the file name of the backend programs, therefore the control logic is necessary here to adjust this part.

In a T4 template, <# #> is used to indicate that this paragraph is a part of the control logic, and the control logic will be placed between the two brackets with pound signs. In the previous example, we need to show different names in different files, so we choose to declare a variable in the Partial Class mentioned earlier and name it AspxName. We then get this name from the defined file and put the name into this variable, and finally show this variable in the T4 template. To show a variable, an equal sign “=” is used, so this control logic will be written in the form of <# = AspxName #>. In this way, when generating this program, a T4 template will automatically replace it with this variable, and our goal will be achieved. The following code example shows how the program has been adjusted for reference.

"Figure VI" Output the variable using control logic

Knowing how to output a variable is one way to complete a simple programs, but of course, most programs are not so simple that you can complete the requirements by simply outputting a variable, so the more complex control logic is necessary here to deal with it. However, even this is not so complex, because as we mentioned, control logic is just as similar to any normal program code. We can directly place the program code into the operating procedures in the control logic section, such as common differences analysis or loop process.

///
/// Responsible for inserting, updating, deleting and selecting basic information
///

The preceding program code may be annotations of a paragraph of back-end programs, and here we may hope that, if no annotation is defined in the file, the annotation line won’t be displayed, including a backslash in front of it and even the two lines of remarks. When writing a program to handle control logic of this kind, it is easy to think of IF bifurcation, which is the same as with the process mode in a T4 template. While introducing the operating principles of T4 templates in the previous paragraphs, we mentioned that the compiled program will convert a T4 template into another file, and the text blocks in it will be converted into the following program code.

this.Write(" /// \r\n");

This means that the text blocks will be directly output, but actually the conversion of control logic is easier. Suppose that no special word, “=” for example, is used. The control logic block will directly copy the program code to another one.

///
<#if(Description != ""){#>
/// <#= Description #>
<#}#>
///

The preceding program code simply demonstrates the usage of placing bifurcation judgement in control logic. After this paragraph of program code is input and saved, you will see the program code converted from the original program code at the backstage, including the following content:

this.Write(" /// \r\n");
#line 29 "C:\ModelGenerator\AspxCsTemplate.tt"
if(Description != ""){
this.Write(" /// ");
#line 30 " C:\ModelGenerator\AspxCsTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(Description));

Through this program after a conversion, we can see some of the results. The conversion of text blocks, as mentioned above, while it can be seen that, for control logic, the position in the original T4 template will be indicated and it will be completely copied. The following also is a text block including the output of a variable and the variable Description is defined in Partial Class.

The writing of the loop section is similar. Place the loop into the control logic block and it will work by combining it with variables and text blocks. Here we also provide a program code for reference.

private SelectList GetOrderByFieldList()
{
var items = new List();
items.Add(new SelectListItem { Value = "Column1", Text = "column 1" });
items.Add(new SelectListItem { Value = "Column2", Text = "column 2" });
(下略)

"Figure VII" Sample of control logic loop

The easiest way to write a T4 template is to paste a piece completed program code and then replace the part in the middle. In the preceding loop sample, the function declarations and list are necessary parts, so they will be saved as text blocks. Later, different program code with unfixed numbers will be generated in accordance with different file definitions, so the loop's control logic should be added. The original program is retained as a textbox and control logic is added at the front and end and then Value as well as Text are replaced.

Here, the use of the T4 template has been introduced. The control logic is the same as that used in programming, so if want to get other effects, you can accomplish those by putting program code in the control logic block, like a function call, the change of variable values, or the declaration of other objects in the control logic. To produce a program, you only need to complete the necessary program code.

Finally, we output files with the TransformText () function, which is located at the backend application that the complier produces for us. This function returns a String object and we can output its object into the file.

Special Characters of Control Logical

From previous paragraphs, we see that control logic blocks can be used to save the program code of the operation process and to output variable values by using <# = #>, in which these control logical blocks are called expression control blocks and output content as ToString to output variable values.

There is also another special character, namely < # @ # > in < # @ the assembly name = \"System. The Core\" # >. It can be used to define the language being used and to import the namespace and external reference.

The last special character is <#+ #> which is used to define properties or methods and is an equivalent of the Partial Class already used above. Here we don't recommend this way of definition in order to avoid making the T4 template too complicated. This content can be moved to the Partial Class for definition.

Conclusions

To save development time, we usually try to get program code of the same type in a consistent architecture, therefore we usually complete the sample's program code first, then the programmers fill out other program code later. However, the emergence of tools like T4 templates makes it possible to automatically produce relevant program codes by writing a T4 template and to produce newly added program code without delay in the future, but also connect to a database and produce program code, for example, to list types without worrying about the desynchronized issue of program code and the database when the data are inserted or deleted. These convenient design tools have helped our development.

Data Sources

1. Code generation and T4 text templates - MSDN - Microsoft
2. Using T4 text templates to generate program codes in the design phase - MSDN - Microsoft
3. The policy of Writing T4 text templates - MSDN - Microsoft