zoukankan      html  css  js  c++  java
  • T4模板使用心得

    TextTemplatingFilePreprocessor 和TextTemplatingFileGenerator 的区别
    TextTemplatingFilePreprocessor 是运行时模板(run-time),在模板保存时生成的是根据模板生成的cs代码,在客户端进行调用才能生成想要的文件。
    TextTemplatingFileGenerator 是设计时模板 design-time,保存模板之后,就直接生成想要的代码。

    **TextTemplatingFileGenerator 在项目中的应用**
    创建一个帮助类,从DbContext中读取实体类名。

    ```

    public class TemplateUtil
    {
    public class TemplateName
    {
    public string ModelName { get; set; }
    public string EntityName { get; set; }
    }
    public static List<TemplateName> GetModelNames()
    {
    List<TemplateName> ModelNames = new List<TemplateName>();
    Type t = new DbContext().GetType();
    PropertyInfo[] PropertyList = t.GetProperties();
    foreach (PropertyInfo item in PropertyList)
    {
    if (item.Name != "Database" && item.Name != "ChangeTracker"&&item.Name != "Configuration"&&item.Name!= "SysAccountRoles"&&item.Name!= "SysRoleMenus"&&item.Name!= "SysRoleFunctions")
    {
    ModelNames.Add(new TemplateName { ModelName= TemplateUtil.ToSingular(item.Name) ,EntityName=item.Name});
    }
    
    }
    return ModelNames;
    }
    
    
            /// <summary>
            /// 单词变成单数形式
            /// </summary>
            /// <param name="word"></param>
            /// <returns></returns>
            public static string ToSingular(string word)
    {
    Regex plural1 = new Regex("(?<keep>[^aeiou])ies$");
    Regex plural2 = new Regex("(?<keep>[aeiou]y)s$");
    Regex plural3 = new Regex("(?<keep>[sxzh])es$");
    Regex plural4 = new Regex("(?<keep>[^sxzhyu])s$");
    Regex plural5= new Regex("(?<keep>[u])s$");
    if (word.ToLower() == "news")
    return word;
    else if(plural1.IsMatch(word))
    return plural1.Replace(word, "${keep}y");
    else if (plural2.IsMatch(word))
    return plural2.Replace(word, "${keep}");
    else if (plural3.IsMatch(word))
    return plural3.Replace(word, "${keep}");
    else if (plural4.IsMatch(word))
    return plural4.Replace(word, "${keep}");
    else if (plural5.IsMatch(word))
    return plural5.Replace(word, "${keep}");
    return word;
    }
            /// <summary>
            /// 单词变成复数形式
            /// </summary>
            /// <param name="word"></param>
            /// <returns></returns>
            public static string ToPlural(string word)
    {
    Regex plural1 = new Regex("(?<keep>[^aeiou])y$");
    Regex plural2 = new Regex("(?<keep>[aeiou]y)$");
    Regex plural3 = new Regex("(?<keep>[sxzh])$");
    Regex plural4 = new Regex("(?<keep>[^sxzhy])$");
    
    if (plural1.IsMatch(word))
    return plural1.Replace(word, "${keep}ies");
    else if (plural2.IsMatch(word))
    return plural2.Replace(word, "${keep}s");
    else if (plural3.IsMatch(word))
    return plural3.Replace(word, "${keep}es");
    else if (plural4.IsMatch(word))
    return plural4.Replace(word, "${keep}s");
    
    return word;
    }
    }

    ```
    从DbContext中读取DbSet属性,获取全部的实体。
    创建一个tangible t4 blank模板 ISvcTemplate.tt


    ```

    <#@ template debug="true" hostSpecific="true" #>
    <#@ output extension=".cs" #>
    <#@ Assembly Name="System.Core" #>
    <#@ Assembly Name="System.Windows.Forms" #>
    <#@ Assembly Name="$(TargetDir)TemplateUtil.dll" #>
    <#@ import namespace="System" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Diagnostics" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Collections" #>
    <#@ import namespace="System.Collections.Generic" #>
    
    
    using System.Collections.Generic;
    using Models;
    using Models.DTOS;
    using Tools;
    <#List<TemplateUtil.TemplateName> ModelNames=TemplateUtil.GetModelNames();
    foreach (var item in ModelNames)
    {#>
    
    
    namespace Services.Template
    {
    public interface I<#=item.ModelName#>Svc
    {
    #region I<#=item.ModelName#>Svc
    /// <summary>
    /// 获取模型
    /// </summary>
    /// <param name="id">主键</param>
    /// <returns></returns>
    <#=item.ModelName#> GetModel(int? id);
    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="pager">分页model</param>
    /// <param name="search">查询model</param>
    /// <returns></returns>
    object GetPager(GridPageModel pager, SearchModel search);
    /// <summary>
    /// 保存
    /// </summary>
    /// <param name="model">model</param>
    /// <returns></returns>
    ResultEx Save(<#=item.ModelName#> model);
    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="ids">主键列表</param>
    /// <returns></returns>
    ResultEx Delete(List<int> ids);
    #endregion
    }
    } 
    <#}#>

    ```
    以上是项目中使用的代码,保存之后生成IService代码

    创建一个SvcTemplate.tt

    ```

    <#@ template debug="true" hostSpecific="true" #>
    <#@ output extension=".cs" #>
    <#@ Assembly Name="System.Core" #>
    <#@ Assembly Name="System.Windows.Forms" #>
    <#@ Assembly Name="$(TargetDir)TemplateUtil.dll" #>
    
    <#@ import namespace="System" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Diagnostics" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Collections" #>
    <#@ import namespace="System.Collections.Generic" #> 
    using System.Linq;
    using System.Collections.Generic;
    using EntityFramework.Extensions;
    using Mehdime.Entity;
    using Models;
    using Models.DTOS;
    using Services.Interfaces;
    using Tools;
    namespace Services.Template
    {
    <#List<TemplateUtil.TemplateName> ModelNames=TemplateUtil.GetModelNames();
    foreach (var item in ModelNames)
    {#>
    public class <#=item.ModelName#>Svc : I<#=item.ModelName#>Svc
    {
    private readonly IDbContextScopeFactory _dbScopeFactory = new DbContextScopeFactory();
    
    #region I<#=item.ModelName#>Svc
    
    public <#=item.ModelName#> GetModel(int? id)
    {
    using (var dbScope = _dbScopeFactory.Create())
    {
    var db = dbScope.DbContexts.Get<ThirdIndustryAssociationDbContext>();
    if (id == null)
    return null;
    else
    return db.<#=item.EntityName#>.SingleOrDefault(p => p.Id == id.Value);
    }
    }
    
    public object GetPager(GridPageModel pager, SearchModel search)
    {
    using (var dbScope = _dbScopeFactory.Create())
    {
    var db = dbScope.DbContexts.Get<ThirdIndustryAssociationDbContext>();
    var query = from p in db.<#=item.EntityName#>
    select p;
    return new PagedList<<#=item.ModelName#>>(query, pager).ToPager();
    }
    }
    
    public ResultEx Save(<#=item.ModelName#> model)
    {
    using (var dbScope = _dbScopeFactory.Create())
    {
    var db = dbScope.DbContexts.Get<ThirdIndustryAssociationDbContext>();
    if (model.Id == 0)
    {
    db.<#=item.EntityName#>.Add(model);
    }
    else
    {
    db.Entry(model).State = System.Data.Entity.EntityState.Modified;
    }
    return ResultEx.Init(db.SaveChanges() > 0);
    }
    }
    
    
    public ResultEx Delete(List<int> ids)
    {
    using (var dbScope = _dbScopeFactory.Create())
    {
    var db = dbScope.DbContexts.Get<ThirdIndustryAssociationDbContext>();
    db.<#=item.EntityName#>.Where(p => ids.Contains(p.Id)).Delete();
    return ResultEx.Init();
    }
    }
    #endregion
    }
    <#}#>
    }

    ```

    以上的代码保存后生成Service代码

    **TextTemplatingFilePreprocessor的使用创建一个控制台Demo,实现批量编写文件**
    新建一个文本模板MultiArticle.tt,自定义工具改为TextTemplatingFilePreprocessor,然后保存修改,生成一个空的MultiArticle.cs

    新建一个MultiArticleCode.cs类

    ```

    public class Article
    {
    public string Title { get; set; }
    
    public string Content { get; set; }
    }
    
    public partial class MultiArticle
    {
    
    public string Subject { get; set; }
    
    public List<Article> ArticleList { get; set; }
    
    
    public MultiArticle(string subject, List<Article> articles) { Subject = subject; ArticleList = articles; }
    
    }

    ```

    创建的MultiArticle类必须和tt模板生成的类在相同的命名空间下。


    添加模板内容如下:


    ```

    <#@ template language="C#" #>
    
    
    <div style="text-align:center;">
    <table width="600" cellpadding="0" cellspacing="0" border="0" style="margin:0 auto;"><tbody><tr><td>
    <div style="600px;text-align:left;font:12px/15px simsun;color:#000;background:#fff;">
    <!-- 水平居中的邮件 -->
    <h1><#=Subject #></h2>
    <table>
    <# foreach(Article item in ArticleList)
    { #>
    <tr><td> <#= item.Title #> </td><td> <#= item.Content #> </td></tr>
    <# } #>
    </table>
    
    </div>
    </td></tr></tbody></table>
    </div>

    ```

    在控制台的main方法中


    ```

    class Program
    {
    static void Main(string[] args)
    {
    string subject = "最新消息";
    var artList = new List<Article>();
    for (int i = 0; i < 4; i++)
    {
    Article art = new Article();
    art.Title = "标题" + i + ":" + Guid.NewGuid();
    art.Content = "内容" + i + ":" + Guid.NewGuid();
    artList.Add(art);
    }
    
    MultiArticle mod = new MultiArticle(subject, artList);
    //TransformText方法是模板编译时自动产生的,
    //这也是前面有提到的,模板MultiArticle.tt的命名要与MultiArticleCode.cs中的类名相同的原因,
    //利用分部类partial,就可以调用该TransformText方法了。
    String pageContent = mod.TransformText();
    //将pageContent保存到任何你想保存的地方
    System.IO.File.WriteAllText("outputPage.html", pageContent, Encoding.UTF8);
    }
    }

    ```

    运行代码,就可以看到生成的文件了。

  • 相关阅读:
    ue4 Windows RawInput Plugin
    UE4 VR中一种比较清晰的UI制作方式
    C# 自定义特性及反射
    C# 委托
    java+orace+hql分页
    数据库小知识总结
    往oracle数据库表中插入五十万条数据
    jsp页面传到action乱码问题
    常见数据库对象与java.sql.Types对照
    Oracle数据库初探
  • 原文地址:https://www.cnblogs.com/lucyliang/p/7170227.html
Copyright © 2011-2022 走看看