Use Visual Studio and the Text Template Transformation Toolkit (T4) to automatically generate code

Page update date :
Page creation date :

Operating environment

Visual Studio
  • Visual Studio 2022
.NET
  • .NET 8.0
Windows
  • Windows 11

Prerequisites

Visual Studio
  • It works even with a somewhat older version
.NET
  • It works even with a somewhat older version

At first

Normally, when creating a code, you think that you will create a code by typing characters manually, but if you want to create a code based on code or data that needs to be created by a specific law, it is convenient to be able to automatically generate it. This section describes how to use the Text Template Transformation Toolkit (T4) to automatically generate code.

Since T4 is a scripting format, it is very easy to generate code in Visual Studio immediately after creating a T4 file. It is written that it automatically generates code, but what is generated is just text, so it is possible to generate anything in text format such as XML and JSON in addition to programs.

The main purpose of this tip is to explain the steps to actually automatically generate code in T4, so I won't go into the details of T4 in depth. If you've ever written a program in C#, you'll understand it right away. If you want to know more about T4, please check the official website and other sites.

precondition

This tip assumes the following:

  • Visual Studio installed on Windows
  • Understanding of C#

T4 can be used in most projects, with the exception of a few, so you are basically free to choose your workload during installation.

Create a project

As mentioned earlier, T4 can be used in most projects, with the exception of a few, so it doesn't matter what type of project you create. In this case, we're creating a project for a console app.

Create a T4 file (.tt)

Right-click a project file or folder to add a new item.

Click the View All Templates button.

Select "General" from the tree on the left, and "Text Templates" from the list in the middle. The file name is arbitrary.

Immediately after creating the file, you may see a dialog similar to the one below. This is displayed when the T4 file is automatically generated. T4 files are automatically generated each time the file is saved or viewed. If you want to perform the automatic generation process as it is, click the "OK" button. If you don't want the dialog to appear every time, check "Don't show this message again". Please note that if an illegal process is described in the T4 file as stated in the dialog, it will be executed accordingly.

After you add the file, you can see that the .tt file has been added to Solution Explorer.

The contents of the file are as follows.

If you extract the .tt file in Solution Explorer, you will see a text file with the same name. This will be the auto-generated file. Since we haven't written anything yet, the contents of the file are empty.

Make an auto-generated file a .cs file

If you're using T4, you'll most likely want to use the .cs extension instead of the default .txt, as the code for your program will be automatically generated. In that case, open the .tt file and output extension .cs save it with .

The auto-generated file should now have a .cs extension. The file name itself is the same as the .tt file, so if you want to change it, change the name of the .tt file.

For the time being, write something and output it to an automatically generated file

In T4, the contents of what you write are basically output as they are. <# ... #> is the T4 process, and the rest is the actual output text.

For example, let's put it in a .tt file as follows.

<#@ 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" #>

public static class Sample
{
  public static void Hello()
  {
    Console.WriteLine("Hello T4!!");
  }
}

When you save it, the auto-generated file should output exactly as you wrote it.

The output is code, so of course it can also be called from Program.cs.

Try to generate code automatically

As mentioned above, I have confirmed that what I wrote will be output as it is, but this is no different from what I wrote normally. Now, let's actually use the T4 script to automatically generate the code. There are a wide variety of ways to make it, so please only give a brief explanation here, and then remake it as you want to make it.

This time, as an example, let's create a method that adds a parse method of each type to string and returns ParseXXXX the specified default value if it cannot be converted. This is just an example of creation, so please add it if you feel that there are any parts that are lacking.

If you can understand C# without explaining the details, it will be quicker to see it, so I will post the full code first.

<#@ 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" #>

<#
  List<string> types = new(){"Int", "Short", "Long", "Float", "Double", "Decimal"}; 
#>

public static class ParseExtensions
{
<# foreach (var type in types) { #>
<#   var typeLower = type.ToLower(); #>
  public static <#= typeLower #> Parse<#= type #>(this string self, <#= typeLower #> defaultValue)
  {
    return <#= typeLower #>.TryParse(self, out var val) ? val : defaultValue;
  }
<# } #>
}

What we are doing is defining the types List for the first time to be created with , and then turning them foreach around with to generate that number of methods. The script part of T4 is written in C#, so if you understand C#, you should be able to understand it.

When you do this, the following code is generated:

public static class ParseExtensions
{
  public static int ParseInt(this string self, int defaultValue)
  {
    return int.TryParse(self, out var val) ? val : defaultValue;
  }
  public static short ParseShort(this string self, short defaultValue)
  {
    return short.TryParse(self, out var val) ? val : defaultValue;
  }
  public static long ParseLong(this string self, long defaultValue)
  {
    return long.TryParse(self, out var val) ? val : defaultValue;
  }
  public static float ParseFloat(this string self, float defaultValue)
  {
    return float.TryParse(self, out var val) ? val : defaultValue;
  }
  public static double ParseDouble(this string self, double defaultValue)
  {
    return double.TryParse(self, out var val) ? val : defaultValue;
  }
  public static decimal ParseDecimal(this string self, decimal defaultValue)
  {
    return decimal.TryParse(self, out var val) ? val : defaultValue;
  }
}

What is generated is code, so you can use it in your program as is.

A little bit more about the T4

Even though the T4 script part can be written in C#, it is necessary to separate the T4 C# code from the C# code that is actually generated. The part that makes that distinction is <# .... #> . <# .... #> is the code that is executed as a script, not the code that is actually output in the script part of T4.

<# .... #> The contents of C# itself are not explained because they are as they are, but <# .... #> there are several types of frames. There are the following ways to use each.

Code Explanation
<#@ .... #> It is mainly used in the declaration of various headers. It is used at the beginning of the T4 code in the assembly declaration of and import .
<# .... #> Write code that is processed by T4. It can be divided into multiple lines. Anything described in this range only acts as an operation and does not affect the output text.
<#= .... #> This is used when you want to output a value such as a variable as an output result. string text = "Sample"; For example, if you write a variable <#= text #> called , will be Sample output.
<#+ .... #> Used to define classes and methods. Basically, it is written at the end of the T4 file.

About the T4 Editor

If you don't have an extension in Visual Studio, opening a .tt file will be displayed in black and white text with no color, which is rather difficult to see.

Some of them may display an extension for .tt files in an easy-to-read manner, so please find the one you like. Since it is made by volunteers, the content may change depending on the time of year and the version of Visual Studio. Extensions can be added from the Visual Studio menu under Extensions.

Here's what I saw in Visual Studio 2022 with an extension called "T4 Language".