MVC中使用T4模板
一、原文地址
大佬的链接:http://www.cnblogs.com/heyuquan/archive/2012/07/26/2610959.html
二、图片释义
1、简单示例,对基本的模块标记
2、根据 上图生成的类,
三、网上大佬写的JuCheap项目中的T4模板
地址:https://gitee.com/jucheap/projects
T4代码:
1 <#@ template language="C#" debug="true" hostspecific="True"#> 2 <#@ include file="$(SolutionDir)JuCheap.Service\MultipleOutputHelper.ttinclude" #> 3 <#@ import namespace="System"#> 4 5 <# 6 string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)"); 7 var files = System.IO.Directory.GetFiles(solutionsPath + @"\JuCheap.Entity", "*.cs"); 8 9 var manager = Manager.Create(Host, GenerationEnvironment); 10 11 //1.开始输出接口契约文件 12 foreach (var filePath in files) 13 { 14 var file = new FileInfo(filePath); 15 var name = file.Name.Replace("Entity.cs",string.Empty); 16 var lowerName =name.ToLower(); 17 //定义输出文件 18 manager.StartNewFile("I"+name+"Service.Partial.cs", string.Empty); 19 #> 20 21 /******************************************************************************* 22 * Copyright (C) JuCheap.Com 23 * 24 * Author: dj.wong 25 * Create Date: <#=DateTime.Now#> 26 * Description: Automated building by [email protected] 27 * 28 * Revision History: 29 * Date Author Description 30 * 2017-08-02 dj.wong optimization 31 *********************************************************************************/ 32 33 using System; 34 using System.Collections.Generic; 35 using System.Linq.Expressions; 36 using JuCheap.Service.Dto; 37 38 namespace JuCheap.Service.Abstracts 39 { 40 /// <summary> 41 /// <#=name#>业务契约 42 /// </summary> 43 public partial interface I<#=name#>Service 44 { 45 /// <summary> 46 /// 添加<#=lowerName#> 47 /// </summary> 48 /// <param name="<#=lowerName#>"><#=lowerName#>实体</param> 49 /// <returns></returns> 50 bool Add(<#=name#>Dto <#=lowerName#>); 51 52 /// <summary> 53 /// 批量添加<#=lowerName#> 54 /// </summary> 55 /// <param name="models"><#=lowerName#>集合</param> 56 /// <returns></returns> 57 bool Add(List<<#=name#>Dto> models); 58 59 /// <summary> 60 /// 编辑<#=lowerName#> 61 /// </summary> 62 /// <param name="<#=lowerName#>">实体</param> 63 /// <returns></returns> 64 bool Update(<#=name#>Dto <#=lowerName#>); 65 66 /// <summary> 67 /// 批量更新<#=lowerName#> 68 /// </summary> 69 /// <param name="<#=lowerName#>s"><#=lowerName#>实体集合</param> 70 /// <returns></returns> 71 bool Update(IEnumerable<<#=name#>Dto> <#=lowerName#>s); 72 73 /// <summary> 74 /// 删除<#=lowerName#> 75 /// </summary> 76 /// <param name="id">Id</param> 77 /// <returns></returns> 78 bool Delete(int id); 79 80 /// <summary> 81 /// 批量删除<#=lowerName#> 82 /// </summary> 83 /// <param name="exp">条件表达式</param> 84 /// <returns></returns> 85 bool Delete(Expression<Func<<#=name#>Dto, bool>> exp); 86 87 /// <summary> 88 /// 获取单条符合条件的 <#=lowerName#> 数据 89 /// </summary> 90 /// <param name="exp">条件表达式</param> 91 /// <returns></returns> 92 <#=name#>Dto GetOne(Expression<Func<<#=name#>Dto, bool>> exp); 93 94 /// <summary> 95 /// 查询符合调价的 <#=lowerName#> 96 /// </summary> 97 /// <param name="exp">过滤条件</param> 98 /// <param name="orderExp">排序条件</param> 99 /// <param name="isDesc">是否是降序排列</param> 100 /// <returns></returns> 101 List<<#=name#>Dto> Query<OrderKeyType>(Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true); 102 103 /// <summary> 104 /// 分页获取<#=lowerName#> 105 /// </summary> 106 /// <param name="queryBase">QueryBase</param> 107 /// <param name="exp">过滤条件</param> 108 /// <param name="orderExp">排序条件</param> 109 /// <param name="isDesc">是否是降序排列</param> 110 /// <returns></returns> 111 ResultDto<<#=name#>Dto> GetWithPages<OrderKeyType>(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true); 112 113 /// <summary> 114 /// 分页获取<#=lowerName#> 115 /// </summary> 116 /// <param name="queryBase">QueryBase</param> 117 /// <param name="exp">过滤条件</param> 118 /// <param name="orderBy">排序条件</param> 119 /// <param name="orderDir">是否是降序排列</param> 120 /// <returns></returns> 121 ResultDto<<#=name#>Dto> GetWithPages(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, string orderBy, string orderDir = "desc"); 122 } 123 } 124 <# 125 // 结束输出文件 126 manager.EndBlock(); 127 } 128 //2.开始生成契约实现文件 129 foreach (var filePath in files) 130 { 131 var file = new FileInfo(filePath); 132 var name = file.Name.Replace("Entity.cs",string.Empty); 133 var lowerName = name.ToLower(); 134 //定义输出文件 135 manager.StartNewFile(name+"Service.Partial.cs", string.Empty); 136 #> 137 138 /******************************************************************************* 139 * Copyright (C) JuCheap.Com 140 * 141 * Author: dj.wong 142 * Create Date: <#=DateTime.Now#> 143 * Description: Automated building by [email protected] 144 * 145 * Revision History: 146 * Date Author Description 147 * 148 *********************************************************************************/ 149 150 using System; 151 using System.Collections.Generic; 152 using System.Data.Entity.Migrations; 153 using System.Linq; 154 using System.Linq.Expressions; 155 using EntityFramework.Extensions; 156 using AutoMapper; 157 using JuCheap.Core; 158 using JuCheap.Core.Extentions; 159 using JuCheap.Entity; 160 using JuCheap.Service.Dto; 161 using Mehdime.Entity; 162 163 namespace JuCheap.Service.Abstracts 164 { 165 /// <summary> 166 /// <#=name#>业务契约 167 /// </summary> 168 public partial class <#=name#>Service : ServiceBase<<#=name#>Entity>, IDependency, I<#=name#>Service 169 { 170 #region 构造函数注册上下文 171 public IDbContextScopeFactory _dbScopeFactory {get;set;} 172 173 //private readonly IDbContextScopeFactory _dbScopeFactory; 174 175 //public <#=name#>Service(IDbContextScopeFactory dbScopeFactory) 176 //{ 177 // _dbScopeFactory = dbScopeFactory; 178 //} 179 180 #endregion 181 182 #region I<#=name#>Service 接口实现 183 184 /// <summary> 185 /// 添加<#=lowerName#> 186 /// </summary> 187 /// <param name="dto"><#=lowerName#>实体</param> 188 /// <returns></returns> 189 public bool Add(<#=name#>Dto dto) 190 { 191 using (var scope = _dbScopeFactory.Create()) 192 { 193 var db = GetDb(scope); 194 var dbSet = GetDbSet(db); 195 var entity = Mapper.Map<<#=name#>Dto, <#=name#>Entity>(dto); 196 dbSet.Add(entity); 197 var count = db.SaveChanges(); 198 return count > 0; 199 } 200 } 201 202 /// <summary> 203 /// 批量添加<#=lowerName#> 204 /// </summary> 205 /// <param name="dtos"><#=lowerName#>集合</param> 206 /// <returns></returns> 207 public bool Add(List<<#=name#>Dto> dtos) 208 { 209 using (var scope = _dbScopeFactory.Create()) 210 { 211 var db = GetDb(scope); 212 var dbSet = GetDbSet(db); 213 var entities = Mapper.Map<List<<#=name#>Dto>, List<<#=name#>Entity>>(dtos); 214 dbSet.AddRange(entities); 215 return db.SaveChanges() > 0; 216 } 217 } 218 219 /// <summary> 220 /// 编辑<#=lowerName#> 221 /// </summary> 222 /// <param name="dto">实体</param> 223 /// <returns></returns> 224 public bool Update(<#=name#>Dto dto) 225 { 226 using (var scope = _dbScopeFactory.Create()) 227 { 228 var db = GetDb(scope); 229 var dbSet = GetDbSet(db); 230 var entity = Mapper.Map<<#=name#>Dto, <#=name#>Entity>(dto); 231 dbSet.AddOrUpdate(entity); 232 return db.SaveChanges() > 0; 233 } 234 } 235 236 /// <summary> 237 /// 批量更新<#=lowerName#> 238 /// </summary> 239 /// <param name="dtos"><#=lowerName#>实体集合</param> 240 /// <returns></returns> 241 public bool Update(IEnumerable<<#=name#>Dto> dtos) 242 { 243 using (var scope = _dbScopeFactory.Create()) 244 { 245 var db = GetDb(scope); 246 var dbSet = GetDbSet(db); 247 var entities = Mapper.Map<IEnumerable<<#=name#>Dto>, IEnumerable<<#=name#>Entity>>(dtos); 248 dbSet.AddOrUpdate(entities.ToArray()); 249 return db.SaveChanges() > 0; 250 } 251 } 252 253 /// <summary> 254 /// 删除<#=lowerName#> 255 /// </summary> 256 /// <param name="id">Id</param> 257 /// <returns></returns> 258 public bool Delete(int id) 259 { 260 using (var scope = _dbScopeFactory.Create()) 261 { 262 var db = GetDb(scope); 263 var dbSet = GetDbSet(db); 264 265 var model = dbSet.FirstOrDefault(item => item.Id == id); 266 dbSet.Remove(model); 267 return db.SaveChanges() > 0; 268 } 269 } 270 271 /// <summary> 272 /// 批量删除<#=lowerName#> 273 /// </summary> 274 /// <param name="exp">条件表达式</param> 275 /// <returns></returns> 276 public bool Delete(Expression<Func<<#=name#>Dto, bool>> exp) 277 { 278 using (var scope = _dbScopeFactory.Create()) 279 { 280 var db = GetDb(scope); 281 var dbSet = GetDbSet(db); 282 var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>(); 283 284 var models = dbSet.Where(where); 285 dbSet.RemoveRange(models); 286 return db.SaveChanges() > 0; 287 } 288 } 289 290 /// <summary> 291 /// 获取单条符合条件的 <#=lowerName#> 数据 292 /// </summary> 293 /// <param name="exp">条件表达式</param> 294 /// <returns></returns> 295 public <#=name#>Dto GetOne(Expression<Func<<#=name#>Dto, bool>> exp) 296 { 297 using (var scope = _dbScopeFactory.CreateReadOnly()) 298 { 299 var db = GetDb(scope); 300 var dbSet = GetDbSet(db); 301 var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>(); 302 var entity = dbSet.AsNoTracking().FirstOrDefault(where); 303 304 return Mapper.Map<<#=name#>Entity, <#=name#>Dto>(entity); 305 } 306 } 307 308 /// <summary> 309 /// 查询符合调价的 <#=lowerName#> 310 /// </summary> 311 /// <param name="exp">过滤条件</param> 312 /// <param name="orderExp">排序条件</param> 313 /// <param name="isDesc">是否是降序排列</param> 314 /// <returns></returns> 315 public List<<#=name#>Dto> Query<OrderKeyType>(Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true) 316 { 317 using (var scope = _dbScopeFactory.CreateReadOnly()) 318 { 319 var db = GetDb(scope); 320 var dbSet = GetDbSet(db); 321 var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>(); 322 var order = orderExp.Cast<<#=name#>Dto, <#=name#>Entity, OrderKeyType>(); 323 var query = GetQuery(dbSet, where, order, isDesc); 324 var list = query.ToList(); 325 return Mapper.Map<List<<#=name#>Entity>, List<<#=name#>Dto>>(list); 326 } 327 } 328 329 /// <summary> 330 /// 分页获取<#=name#> 331 /// </summary> 332 /// <param name="queryBase">QueryBase</param> 333 /// <param name="exp">过滤条件</param> 334 /// <param name="orderExp">排序条件</param> 335 /// <param name="isDesc">是否是降序排列</param> 336 /// <returns></returns> 337 public ResultDto<<#=name#>Dto> GetWithPages<OrderKeyType>(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true) 338 { 339 using (var scope = _dbScopeFactory.CreateReadOnly()) 340 { 341 var db = GetDb(scope); 342 var dbSet = GetDbSet(db); 343 var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>(); 344 var order = orderExp.Cast<<#=name#>Dto, <#=name#>Entity, OrderKeyType>(); 345 var query = GetQuery(dbSet, where, order, isDesc); 346 347 var query_count = query.FutureCount(); 348 var query_list = query.Skip(queryBase.Start).Take(queryBase.Length).Future(); 349 var list = query_list.ToList(); 350 351 var dto = new ResultDto<<#=name#>Dto> 352 { 353 recordsTotal = query_count.Value, 354 data = Mapper.Map<List<<#=name#>Entity>, List<<#=name#>Dto>>(list) 355 }; 356 return dto; 357 } 358 } 359 360 /// <summary> 361 /// 分页获取<#=name#> 362 /// </summary> 363 /// <param name="queryBase">QueryBase</param> 364 /// <param name="exp">过滤条件</param> 365 /// <param name="orderBy">排序条件</param> 366 /// <param name="orderDir">排序类型:desc(默认)/asc</param> 367 /// <returns></returns> 368 public ResultDto<<#=name#>Dto> GetWithPages(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, string orderBy, string orderDir = "desc") 369 { 370 using (var scope = _dbScopeFactory.CreateReadOnly()) 371 { 372 var db = GetDb(scope); 373 var dbSet = GetDbSet(db); 374 var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>(); 375 //var order = orderExp.Cast<<#=name#>Dto, <#=name#>Entity, OrderKeyType>(); 376 var query = GetQuery(dbSet, where, orderBy, orderDir); 377 378 var query_count = query.FutureCount(); 379 var query_list = query.Skip(queryBase.Start).Take(queryBase.Length).Future(); 380 var list = query_list.ToList(); 381 382 var dto = new ResultDto<<#=name#>Dto> 383 { 384 recordsTotal = query_count.Value, 385 data = Mapper.Map<List<<#=name#>Entity>, List<<#=name#>Dto>>(list) 386 }; 387 return dto; 388 } 389 } 390 391 #endregion 392 } 393 } 394 <# 395 // 结束输出文件 396 manager.EndBlock(); 397 } 398 #> 399 400 401 <# 402 manager.StartNewFile("AutoMapperConfiguration.Partial.cs", string.Empty); 403 #> 404 405 406 /******************************************************************************* 407 * Copyright (C) JuCheap.Com 408 * 409 * Author: dj.wong 410 * Create Date: 2015/8/7 11:12:12 411 * Description: Automated building by [email protected] 412 * 413 * Revision History: 414 * Date Author Description 415 * 416 *********************************************************************************/ 417 418 using AutoMapper; 419 using JuCheap.Entity; 420 using JuCheap.Service.Dto; 421 422 namespace JuCheap.Service 423 { 424 /// <summary> 425 /// AutoMapper 配置 426 /// </summary> 427 public partial class AutoMapperConfiguration 428 { 429 /// <summary> 430 /// 配置AutoMapper 431 /// </summary> 432 public static void Config() 433 { 434 <# 435 //1.开始输出接口契约文件 436 foreach (var filePath in files) 437 { 438 var file = new FileInfo(filePath); 439 var name = file.Name.Replace("Entity.cs",string.Empty); 440 var lowerName =name.ToLower(); 441 //定义输出文件 442 #> 443 Mapper.CreateMap<<#=name#>Entity, <#=name#>Dto>(); 444 Mapper.CreateMap<<#=name#>Dto, <#=name#>Entity>(); 445 <# 446 } 447 #> 448 } 449 } 450 } 451 <# 452 // 结束输出文件 453 manager.EndBlock(); 454 // 执行编译 455 manager.Process(true); 456 #>
引用的ttInclude代码:
1 <#@ assembly name="System.Core" 2 #><#@ assembly name="System.Data.Linq" 3 #><#@ assembly name="EnvDTE" 4 #><#@ assembly name="System.Xml" 5 #><#@ assembly name="System.Xml.Linq" 6 #><#@ import namespace="System.Collections.Generic" 7 #><#@ import namespace="System.IO" 8 #><#@ import namespace="System.Text" 9 #><#@ import namespace="Microsoft.VisualStudio.TextTemplating" 10 #><#+ 11 // https://raw.github.com/damieng/DamienGKit 12 // http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited 13 // Manager class records the various blocks so it can split them up 14 class Manager { 15 private class Block { 16 public String Name; 17 public string FilePath; 18 public int Start, Length; 19 public bool IncludeInDefault; 20 } 21 22 private Block currentBlock; 23 private readonly List<Block> files = new List<Block>(); 24 private readonly Block footer = new Block(); 25 private readonly Block header = new Block(); 26 private readonly ITextTemplatingEngineHost host; 27 private readonly StringBuilder template; 28 protected readonly List<String> generatedFileNames = new List<String>(); 29 30 public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) { 31 return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template); 32 } 33 34 public void StartNewFile(String name, string filePath) { 35 if (name == null) 36 throw new ArgumentNullException("name"); 37 CurrentBlock = new Block { Name = name, FilePath = filePath }; 38 } 39 40 public void StartFooter(bool includeInDefault = true) { 41 CurrentBlock = footer; 42 footer.IncludeInDefault = includeInDefault; 43 } 44 45 public void StartHeader(bool includeInDefault = true) { 46 CurrentBlock = header; 47 header.IncludeInDefault = includeInDefault; 48 } 49 50 public void EndBlock() { 51 if (CurrentBlock == null) 52 return; 53 CurrentBlock.Length = template.Length - CurrentBlock.Start; 54 if (CurrentBlock != header && CurrentBlock != footer) 55 files.Add(CurrentBlock); 56 currentBlock = null; 57 } 58 59 public virtual void Process(bool split, bool sync = true) { 60 if (split) { 61 EndBlock(); 62 String headerText = template.ToString(header.Start, header.Length); 63 String footerText = template.ToString(footer.Start, footer.Length); 64 String outputPath = Path.GetDirectoryName(host.TemplateFile); 65 files.Reverse(); 66 if (!footer.IncludeInDefault) 67 template.Remove(footer.Start, footer.Length); 68 foreach(Block block in files) { 69 String myPath = block.FilePath; 70 if(!string.IsNullOrWhiteSpace(myPath)) 71 outputPath = myPath; 72 String fileName = Path.Combine(outputPath, block.Name); 73 String content = headerText + template.ToString(block.Start, block.Length) + footerText; 74 generatedFileNames.Add(fileName); 75 CreateFile(fileName, content); 76 template.Remove(block.Start, block.Length); 77 } 78 if (!header.IncludeInDefault) 79 template.Remove(header.Start, header.Length); 80 } 81 } 82 83 protected virtual void CreateFile(String fileName, String content) { 84 if (IsFileContentDifferent(fileName, content)) 85 File.WriteAllText(fileName, content); 86 } 87 88 public virtual String GetCustomToolNamespace(String fileName) { 89 return null; 90 } 91 92 public virtual String DefaultProjectNamespace { 93 get { return null; } 94 } 95 96 protected bool IsFileContentDifferent(String fileName, String newContent) { 97 return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); 98 } 99 100 private Manager(ITextTemplatingEngineHost host, StringBuilder template) { 101 this.host = host; 102 this.template = template; 103 } 104 105 private Block CurrentBlock { 106 get { return currentBlock; } 107 set { 108 if (CurrentBlock != null) 109 EndBlock(); 110 if (value != null) 111 value.Start = template.Length; 112 currentBlock = value; 113 } 114 } 115 116 private class VSManager: Manager { 117 private readonly EnvDTE.ProjectItem templateProjectItem; 118 private readonly EnvDTE.DTE dte; 119 private readonly Action<String> checkOutAction; 120 private readonly Action<List<String>> projectSyncAction; 121 122 public override String DefaultProjectNamespace { 123 get { 124 return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString(); 125 } 126 } 127 128 public override String GetCustomToolNamespace(string fileName) { 129 return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString(); 130 } 131 132 public override void Process(bool split, bool sync) { 133 if (templateProjectItem.ProjectItems == null) 134 return; 135 base.Process(split, sync); 136 if (sync) 137 projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); 138 } 139 140 protected override void CreateFile(String fileName, String content) { 141 if (IsFileContentDifferent(fileName, content)) { 142 CheckoutFileIfRequired(fileName); 143 File.WriteAllText(fileName, content); 144 } 145 } 146 147 internal VSManager(ITextTemplatingEngineHost host, StringBuilder template) 148 : base(host, template) { 149 var hostServiceProvider = (IServiceProvider)host; 150 if (hostServiceProvider == null) 151 throw new ArgumentNullException("Could not obtain IServiceProvider"); 152 dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); 153 if (dte == null) 154 throw new ArgumentNullException("Could not obtain DTE from host"); 155 templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile); 156 checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); 157 projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); 158 } 159 160 private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List<String> keepFileNames) { 161 var keepFileNameSet = new HashSet<String>(keepFileNames); 162 var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>(); 163 var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + "."; 164 foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) 165 projectFiles.Add(projectItem.FileNames[0], projectItem); 166 167 // Remove unused items from the project 168 foreach (var pair in projectFiles) 169 if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) 170 pair.Value.Delete(); 171 172 // Add missing files to the project 173 foreach(String fileName in keepFileNameSet) 174 if (!projectFiles.ContainsKey(fileName)) 175 templateProjectItem.ProjectItems.AddFromFile(fileName); 176 } 177 178 private void CheckoutFileIfRequired(String fileName) { 179 var sc = dte.SourceControl; 180 if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) 181 checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); 182 } 183 } 184 } #>
用到的语法:
1、string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");
T4模板中获取当前解决方案的文件路径。
2、var files = System.IO.Directory.GetFiles(solutionsPath + @"\JuCheap.Entity", "*.cs");
获取JuCheap.Entity项目中所有cs扩展名的文件信息。
3、var manager = Manager.Create(Host, GenerationEnvironment);
在引用的ttInclude中,创建一个模板管理者的对象,用于操作和生成数据。
4、 public partial interface I<#=name#>Service
在<# string name="ClassName" #> 中声明的变量,
可以在文本块中以<#=name#>的形式调用。(name为声明的变量名称)
5、 manager.EndBlock();
在引用的ttInclude中,结束对新服务类的内容赋值,
将文件对象添加到文件集合中。
6、manager.Process(true);
在引用的ttInclude中,结束数据生成,编译运行,生成相应的文件。
四、总结
因为有CodeSmith的使用经验,所以在看到T4模板使用方法时,
没有想象的那么困难。
纸上得来终觉浅,绝知此事要躬行。
目前只是看网上大佬的教程,还没有在项目中实际使用过,
还有许多未知的问题和操作。