本文档所有内容非官方解释注解,内容多数为个人理解,紧供个人参考
T4模板简介
介绍我就不介绍了 😊
T4模板类似于一种注入式代码语言,以C#为基础识别 ,类似于当前.tt模板继承于某一个类型,并在保存时由IDE执行当前代码
并生成输出内容
- <##>
- <#=#>
- <#+#>
- <#@ import namespace=""#>
- <#@ include file=""#>
等五种代码标签
<!-- 模板配置 语言C# 基本无需修改 -->
<#@ template language="C#" debug="false" hostspecific="true"#>
<!-- 引入模板内容 处理方式? -->
<#@ include file="EF6.Utility.CS.ttinclude"#>
<!-- 文件输出格式 -->
<#@ output extension=".cs"#>
<#
// C# 代码块
可以输入任何代码
#>
<#+
// 为当前类添加 内容 如添加 方法 类型等
#>
// 输出等号(=)后面的内容
<#="输出的内容"#>
直奔主题
基于使用主义,不赘述其他内容,从模板内容简单介绍
创建名为test.tt的T4模板
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#>
<#@ output extension=".cs"#>
// 尝试输出第一部分内容
<#="Hello T4" #>
保存当前TT模板出现错误提示
错误 正在编译转换: 当前上下文中不存在名称“ArgumentNotNull”
杂项文件 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\
Microsoft\Entity Framework Tools\Templates\Includes\EF6.Utility.CS.ttinclude 1497
点击错误查看错误位置
public class EdmMetadataLoader
{
private readonly IDynamicHost _host;
private readonly System.Collections.IList _errors;
public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors)
{
/*
当前上下文中不存在名称“ArgumentNotNull”
*/
ArgumentNotNull(host, "host");
ArgumentNotNull(errors, "errors");
_host = host;
_errors = errors;
}
......
}
基于上述情况在,当前模板中扩展一个 ArgumentNotNull 方法竟然可以保存并生成对应的文档
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#>
<#@ output extension=".cs"#>
// 尝试输出第一部分内容
<#="Hello T4" #>
<#+
public static void ArgumentNotNull<T>(T arg, string name) where T : class
{
if (arg == null)
{
throw new ArgumentNullException(name);
}
}
#>
生成的test.cs,文件
Hello T4
总结
综上可见,当前test.tt疑似继承 EF6.Utility.CS.ttinclude 或本身就是 其的一部分,在使用EF6的T4模板时只需要在当前页面实现一个ArgumentNotNull方法,至于为什么是静态,应该是和类型调用有关,此处本人未作其他探究,希望以后有机会研究研究。