T4 多文件生成说明
1.安装T4,自动生成文件 Manager.ttinclude
<#@ assembly name="System.Core"#>
<#@ assembly name="System.Data.Linq"#>
<#@ assembly name="EnvDTE"#>
<#@ assembly name="System.Xml"#>
<#@ assembly name="System.Xml.Linq"#>
<#@ import namespace="System"#>
<#@ import namespace="System.CodeDom"#>
<#@ import namespace="System.CodeDom.Compiler"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.Data.Linq"#>
<#@ import namespace="System.Data.Linq.Mapping"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Linq"#>
<#@ import namespace="System.Reflection"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="System.Xml.Linq"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+
// Manager class records the various blocks so it can split them up
class Manager {
private class Block {
public String Name;
public int Start, Length;
}
private Block currentBlock;
private List<Block> files = new List<Block>();
private Block footer = new Block();
private Block header = new Block();
private ITextTemplatingEngineHost host;
private StringBuilder template;
protected List<String> generatedFileNames = new List<String>();
public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
}
public void StartNewFile(String name) {
if (name == null)
throw new ArgumentNullException("name");
CurrentBlock = new Block { Name = name };
}
public void StartFooter() {
CurrentBlock = footer;
}
public void StartHeader() {
CurrentBlock = header;
}
public void EndBlock() {
if (CurrentBlock == null)
return;
CurrentBlock.Length = template.Length - CurrentBlock.Start;
if (CurrentBlock != header && CurrentBlock != footer)
files.Add(CurrentBlock);
currentBlock = null;
}
public virtual void Process(bool split) {
if (split) {
EndBlock();
String headerText = template.ToString(header.Start, header.Length);
String footerText = template.ToString(footer.Start, footer.Length);
String outputPath = Path.GetDirectoryName(host.TemplateFile);
files.Reverse();
foreach(Block block in files) {
String fileName = Path.Combine(outputPath, block.Name);
String content = headerText + template.ToString(block.Start, block.Length) + footerText;
generatedFileNames.Add(fileName);
CreateFile(fileName, content);
template.Remove(block.Start, block.Length);
}
}
}
protected virtual void CreateFile(String fileName, String content) {
if (IsFileContentDifferent(fileName, content))
File.WriteAllText(fileName, content);
}
public virtual String GetCustomToolNamespace(String fileName) {
return null;
}
public virtual String DefaultProjectNamespace {
get { return null; }
}
protected bool IsFileContentDifferent(String fileName, String newContent) {
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
}
private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
this.host = host;
this.template = template;
}
private Block CurrentBlock {
get { return currentBlock; }
set {
if (CurrentBlock != null)
EndBlock();
if (value != null)
value.Start = template.Length;
currentBlock = value;
}
}
private class VSManager: Manager {
private EnvDTE.ProjectItem templateProjectItem;
private EnvDTE.DTE dte;
private Action<String> checkOutAction;
private Action<IEnumerable<String>> projectSyncAction;
public override String DefaultProjectNamespace {
get {
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
}
}
public override String GetCustomToolNamespace(string fileName) {
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
}
public override void Process(bool split) {
if (templateProjectItem.ProjectItems == null)
return;
base.Process(split);
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
}
protected override void CreateFile(String fileName, String content) {
if (IsFileContentDifferent(fileName, content)) {
CheckoutFileIfRequired(fileName);
File.WriteAllText(fileName, content);
}
}
internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
: base(host, template) {
var hostServiceProvider = (IServiceProvider) host;
if (hostServiceProvider == null)
throw new ArgumentNullException("Could not obtain IServiceProvider");
dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
if (dte == null)
throw new ArgumentNullException("Could not obtain DTE from host");
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
}
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
var keepFileNameSet = new HashSet<String>(keepFileNames);
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames()) + ".";
foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
projectFiles.Add(projectItem.get_FileNames(), projectItem);
// Remove unused items from the project
foreach(var pair in projectFiles)
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
pair.Value.Delete();
// Add missing files to the project
foreach(String fileName in keepFileNameSet)
if (!projectFiles.ContainsKey(fileName))
templateProjectItem.ProjectItems.AddFromFile(fileName);
}
private void CheckoutFileIfRequired(String fileName) {
var sc = dte.SourceControl;
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
}
}
} #>
Manager.ttinclude
2.添加 .tt 文件
3 引用 Manager.ttinclude 文件
4. 按照需求编写代码,完成
<#
var manager= Manager.Create(Host,GenerationEnvironment);
#>
<#
for(int i=;i<;i++)
{
manager.StartNewFile((i+).ToString()+"xx.cs"); #>
public class xx<#=i#>
{
public string name{set;get;}
}
<# manager.EndBlock();
}
manager.Process(true);
#>
T4 多文件生成说明的更多相关文章
- T4 模板自动生成带注释的实体类文件
T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll 生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 如果你没有 ...
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面
前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...
- 让T4脱离VS生成代码
让T4脱离VS生成代码 最近项目快结束:空闲时间相对多一点:为了以后工作方便点:索性研究了VS的T4: 写个代码生成器:以后可以通过代码生成器调用项目里面的Dll直接生成代码或者xml: 应用以下两个 ...
- PetaPoco T4模板修改生成实体
PetaPoco T4 模板生成的实体类全部包含再一个.CS文件中.通过修改PetaPoco的T4模板,生成单文件实体. 1.生成单CS文件模板: SigleFile.ttinclude <#@ ...
- 【转】- 使用T4模板批量生成代码
前言 之前在 “使用T4模板生成代码 - 初探” 文章简单的使用了T4模板的生成功能,但对于一个模板生成多个实例文件,如何实现这个方式呢?无意发现一个解决方案 “MultipleOutputHelpe ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
- Android first---xml文件生成与解析
一.使用append进行xml生成 Message类属性:private String body; private String date; private String a ...
- ActiveX: 如何用.inf和.ocx文件生成cab文件
ActiveX: 如何用.inf和.ocx文件生成cab文件
- ssl证书生成:cer&jks文件生成摘录
一.生成.jks文件 1.keystore的生成: 分阶段生成: keytool -genkey -alias yushan(别名) -keypass yushan(别名密码) -keyalg ...
随机推荐
- Mysql SQL CAST()函数
(1).CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型.以下例子用于将文本字符串'12'转换为整型: SELECT CAST('12' AS int) (2).返回值是 ...
- Docker Compose 使用示例
一般步骤 1.定义Dockerfile,方便迁移到任何地方: 2.编写docker-compose.yml文件: 3.运行docker-compose up启动服务 示例 准备工作:提前下载好镜像: ...
- 第二十篇 Linux条件测试语句相关知识点介绍
条件测试语句的格式如下: [ 条件表达式 ] # 条件表达式两侧各有一个空格 按测试对象不同,条件测试语句共分为4中类型: 文件测试语句 逻辑测试语句 整数值比较语句 字符串比较语句 ...
- 1.3 使用jmeter进行http接口测试
来源: http://www.cnblogs.com/alisapan/p/6150309.html 此篇纯是搬运记载.. 一.测试需求描述 1. 本次测试的接口为http服务端接口 2. 接口的 ...
- 吴裕雄 python 机器学习——集成学习AdaBoost算法分类模型
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...
- 吴裕雄 python 机器学习——局部线性嵌入LLE降维模型
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt from sklearn import datas ...
- Django 报错no sucn column: OpretionalError
1.报错原因:新增的字段未能同步数据库 2.解决办法:删除整个数据库,然后重新编译,然后over 1.rm -rf db.sqlites3 #删除数据库 2.rm -rf cmdb/migrarion ...
- Python连载59-HTTP首部字段和消息头,Thinker简介
一.首部字段或者消息头 1.下面几个类型都是请求的: User-Agent:关于浏览器和它平台的消息,如Mozilla5.0 Accept:客户端能处理的页面的类型,如text/html Accept ...
- SpringBoot踩坑记(HTTP 400 错误)
HTTP 400 错误 复现错误 ajax请求后台数据时有时会报 HTTP 400 错误 - 请求无效 (Bad request);出现这个请求无效报错说明请求没有进入到后台服务里:原因:1)前端提交 ...
- HGAME 2020 week1 web
1.Cosmos 的博客 知识点:git source code leak 2.接 头 霸 王 Description HGAME Re:Dive 开服啦~ 打开题目,提示了"头" ...