jacklmjie / dotnet-template-T4Sample

T4Sample

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

T4Sample (How to Use T4 in .NET Core + VSCode)

This is a sample to create a table Entity class using T4.

In Japanese, see also .NET Core+VS CodeでもT4 テンプレートエンジンでコード生成したい!

Environments

What is "T4"?

T4 means "Text Template Transformation Toolkit". It is bundled to Visual Studio since 2008.

It is often used for automatic code generation such as table definition classes.

This sample uses Mono.TextTemplating which is a T4 implemented by Mono Project.

Processes

1. Create Project

> dotnet new console

2. Add LangVersion to .csproj

  • Set LangVersion to 8.0.
   <PropertyGroup>
+    <LangVersion>8.0</LangVersion>
     <OutputType>Exe</OutputType>
     <TargetFramework>netcoreapp3.0</TargetFramework>
   </PropertyGroup>

3. Create Table and Column Entities

4. Install Mono.TextTemplating from NuGet

The program code generated by T4 file depends on this package.

> dotnet add package Mono.TextTemplating --version 2.0.5

5. Install T4 Cli Tool

Add DotNetCliToolReference in csproj to use dotnet-t4-project-tool.

  <ItemGroup>
+    <DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
     <PackageReference Include="Mono.TextTemplating" Version="2.0.5" />
   </ItemGroup>

6. Add Task to Prebuild and Cleanup

Define Target Files

Define TextTemplate and Genarated using Glob.

  <ItemGroup>
     <DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
     <PackageReference Include="Mono.TextTemplating" Version="2.0.5" />
+    <TextTemplate Include="**\*.tt" />
+    <Generated Include="**\*.Generated.cs" />
   </ItemGroup>

Define Prebuild Task

Define Task to run dotnet t4.

  • %(TextTemplate.Identity)
    • T4 File Paths such as foo/Template.tt.
  • $(RootNameSpace)
    • Default Namespace. If you changed the T4 class's namespace, set it exactly.
  • %(TextTemplate.Filename)
    • T4 File Name.
   </ItemGroup>
+  <Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
+    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity) -c $(RootNameSpace).%(TextTemplate.Filename) -o %(TextTemplate.Filename).Generated.cs" />
+  </Target>

Define Cleanup Task

Define Task to delete *.Generated.cs.

   </Target>
+  <Target Name="TextTemplateClean" AfterTargets="Clean">
+    <Delete Files="@(Generated)" />
+  </Target>

7. Create T4 Interface and define implements

TransFormText(), Called by Program to use T4 Classes are defined in *.Generated.cs. But *.Generated.cs is generated just before the build. So calling TransFormText() will cause a compile error because there is no definition at before build time.

This sample avoids this by using the "default implementation of interfaces".

using System;

namespace T4Sample
{
    public interface ITextTemplate
    {
        string TransformText() => throw new NotImplementedException();
    }
}

8. Create T4 Template File & Class

Note that T4 class should be defined with partial class.

9. Call T4 Class in Program.cs

Note that variable type should be an interface. Don't use var or TableEntityTemplate.

Build & Run

Build

> dotnet build

TableEntityTemplate.Generated.cs is generated and the program is built including it.

Run

dotnet run does not cause Beforebuild-Event, you should execute dotnet build first.

> dotnet run

Result

using System;
using System.Collections.Generic;

namespace MyNameSpace
{
    /// <summery>
    /// Stores employee information.
    /// </summery>
    public class StaffMaster
    {
        public int StaffId { get; }

        public string StaffName { get; set; }

        /// <summery>
        /// Home Address.
        /// </summery>
        public string Address { get; set; }

        public DateTime CreatedDate { get; set; }

        public StaffMaster(
            int staffId
        )
        {
            StaffId = staffId;
        }

        public StaffMaster(
            int staffId,
            string staffName,
            string address,
            DateTime createdDate
        )
        {
            StaffId = staffId;
            StaffName = staffName;
            Address = address;
            CreatedDate = createdDate;
        }
    }
}

References

About

T4Sample


Languages

Language:C# 100.0%