CodeSmith 介紹

 代碼生成器做用                                                                                              

        中國有句古語叫作「工欲善其事,必先利其器」,用通俗的話來講就是「磨刀不誤砍柴功」,古人的這些話告訴咱們:要把事情作好,事先應該準備合適的工具。工具不單單包括器具,數據庫

 還包括思想、理論、經驗、道德、法律等一切能解決問題的有形和無形的東西。編程

 CodeSmith介紹                                                                                            

     CodeSmith是一個代碼生成器,能夠用來大量生成代碼的。用起來其實也很簡單,但是許多人都不能入門。大部分的代碼生成工具都是須要模板的,這個很好理解,模板就是一段代碼,ide

裏面留幾個洞,這個洞會被數據庫的字段名或表名等填充,CodeSmith的最多的用法就是鏈接數據庫,而後把數據庫信息取出來去替換用戶提供的模板中關鍵字,這就是代碼生成的原理。工具

爲了生成更靈活,模板和關鍵字能夠混合在一塊兒寫,這個蠻怪異的,不過你看懂了也就無所謂了。學習

     當生成應用程序時,不管是編寫數據訪問代碼仍是生成自定義集合,你會發現常常須要重複完成某些特定的任務。這時 CodeSmith 就顯得特別有用,由於你能夠編寫模板自動完成this

這些任務,從而不只提升你的工做效率,並且可以自動完成那些最爲乏味的任務。spa

 CodeSmith界面                                                                                            

     CodeSmith 的代碼編寫界面跟常見的開發IDE很相似。經常使用的就是Bulid Templete, Generate,以及Output  VIEW。3d

     

 CodeSmith 語法介紹                                                                                       

      

1.註釋

<%-- 這是一個C#語言的模板 --%>

2.加載使用訪問數據庫的組件SchemaExplorer,並聲明其使用的命名空間 

<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>

3.聲明表對象

<%@ Property Name="TargetTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="TargetTable that the object is based on." %>

3.聲明視圖對象

<%@ Property Name="TargetView" Type="SchemaExplorer.ViewSchema" Category="Context" Description="TargetView that the object is based on." %>

4.設置輸入信息框
<%@ Property Name="Author" Type="String" Category="Context" Description="做者" %>

5.編寫C# 語言塊  
   
     5.1  <%           %>
     5.2  <script runat="template">
               private string GetDesc(string name)
               {
                  string temp=string.Empty;
                  temp+="//做者:"+name+" Create Date:"+System.DateTime.Now.ToString(); 
                return temp;
               }
            </script>
     5.3  建立.cs文件,聲明中src 引用
            <%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="Common.cs" Description="指明是一個C#語言版本" Inherits="Common" %>

6.賦值<%=    %>

7.相關的數據庫對象
   7.1 表名:TargetTable.Name
   7.2 表列結合:TargetTable.Columns
   7.3 列描述:column.Description 

 

CodeSmith 生成實體類模板                                                                                          

有了上述的語法知識,咱們開始編寫一個簡單的實體對象(Model),最終結果是日誌

//============================================================
///Create By:QingQing
//============================================================

using System;
using System.Collections.Generic;
using System.Text;

namespace POP.Domain
{    
    [Serializable()]  
    public class Area 
    {
            /// <summary>
            /// 
            /// </summary>
            public long  Areaid {get;set;}
            /// <summary>
            /// 
            /// </summary>
            public string  Areaname {get;set;}
            /// <summary>
            /// 
            /// </summary>
            public string  Aliasname {get;set;}
            /// <summary>
            /// 
            /// </summary>
            public long?  Parentid {get;set;}
            /// <summary>
            /// 
            /// </summary>
            public long?  Sortno {get;set;}
            /// <summary>
            /// T:有效,F:無效
            /// </summary>
            public string  Valid {get;set;}
    }    
}

思考一下,using 引用的命名空間是固定的,get set熟悉是固定的,剩下的就是要從數據庫裏獲取表對象進行填充了,上模板。code

<%-- 這是一個C#語言的模板 --%>
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="Common.cs" Description="指明是一個C#語言版本" Inherits="Common" %>
<%-- 加載使用訪問數據庫的組件SchemaExplorer,並聲明其使用的命名空間 --%>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>
<%-- 經過這個數據表類型的變量獲得相應的表的信息:TableSchema(表)  ViewSchema(視圖)  --%>
<%@ Property Name="TargetTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="TargetTable that the object is based on." %>
<%@ Property Name="Author" Type="String" Category="Context" Description="做者" %>
<%--代碼須要的輸入值變量--%>
<%@ Property Name="NameSpace" Default="MyTest.DoMain" Type="String" Category="Context"  Description="生成代碼是須要輸入的變量" %>

<%--<%=GetDesc(Author)%>--%>
<% PrintHeader(Author); %>
using System;
using System.Collections.Generic;
using System.Text;

namespace <%=NameSpace %>
{    
    [Serializable()]  
    public class <%=GetNewTableName(TargetTable.Name)%> 
    {
        <% 
        foreach (ColumnSchema column in TargetTable.Columns)
         {           
        %>
            /// <summary>
            /// <%=column.Description %>
            /// </summary>
            public <%=GetCSharpTypeFromDBFieldType(column) %>  <%=GetNewColoumName(column.Name)%> {get;set;}
        <%
        }
        %>    
    }    
}

<script runat="template">
/// <summary>
///// 設置文件描述
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private string GetDesc(string name)
{
    string temp=string.Empty;
    temp+="//做者:"+name+" Create Date:" +System.DateTime.Now.ToString(); 
    return temp;
}

/// <summary>
/// 設置文件名稱,後綴名
/// </summary>
/// <returns></returns>
public override string GetFileName()
{
    return this.TargetTable + ".cs";
}
</script>

編譯模板                                                                                                              

模板編寫完成,要進行編譯,確認語法是否經過。輸出日誌框,錯誤列表都是咱們的好幫手。

 

使用模板生成文件                                                                                              

OK,模板編譯經過咱們就要見證奇蹟的時刻了。

批量生成文件                                                                                                         

單個文件可以生成了,是否是很方便呢,可是聰明的你確定發現,怎沒有提供批量生成的按鈕呢?對的,這就須要咱們繼續編寫模板來進行實現了。

批量生成要注意一下幾點:

  1. 註冊生成單個模板的文件
  2. 添加單個文件須要使用的文本框
  3. 註冊獲取數據庫的對象
  4. 編寫方法遍歷數據庫的表對象
  5. 編寫獲取輸出文件的路徑

    如下就是模板,一樣的右鍵點擊模板,Execute,填寫相關參數,選擇數據庫,Generate,生成的文件就會出如今選擇的文件夾中
<%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="生成整個表" Debug="True" ResponseEncoding="UTF-8"%>

<%-- 註冊實體層Entity模板 --%>
<%@ Register Name="EntityTemplate" Template="BaseForModel.cst" MergeProperties="Flase" ExcludeProperties=""%>
<%@ Property Name="Author" Type="String" Category="02.做者" Description="做者" %>
<%-- 獲取整個數據庫對象 --%>
<%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" DeepLoad="True" Optional="False" Category="01. 獲取數據庫對象" Description="獲取整個數據庫對象"%>


<%
//建立實體層Entity類
this.GenerateEntityClasses();
//Debug模式下的信息[Debug="True"]
Debug.WriteLine("Success");
%>

<script runat="template">
    //生成實體Entity類
private void GenerateEntityClasses()
{
        //獲取模板對象
        CodeTemplate Template =new EntityTemplate();
        foreach(TableSchema table in this.SourceDatabase.Tables)
        {
            string FileDirectory = OutputDirectory +"\\"+ GetNewTableName(table.Name)  +".cs";
            //設置模板的相關內容(Table名稱 ,做者名稱)
            Template.SetProperty("TargetTable",table);
             Template.SetProperty("Author",Author);
            //文件輸出
            Template.RenderToFile(FileDirectory,true);
            Debug.WriteLine(FileDirectory +" 建立成功.");
        }
}

/// <summary>
/// 獲取新的TableName(首字母大寫,去掉下劃線)
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetNewTableName(string name)
{
      string table=name.Substring(1).ToLower();
      string tempTableName=string.Empty;
      if(table.IndexOf('_')>0)
      {          
            string[] temp=table.Split('_');
            for (int i = 0; i < temp.Length; i++)
            {               
               tempTableName+=System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(temp[i]); //設置首字母大寫
            }   
      }
      else
      {
          tempTableName=System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(table); //設置首字母大寫          
      }
    return tempTableName;
}

    //解決方案輸出路徑
    private string Directory = String.Empty;
    
    [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))] 
    [Optional, NotChecked]
    [DefaultValue("")]
    public string OutputDirectory 
    { 
        get
        {
            return Directory;
        }
        set
        {
            if (value.EndsWith("\\")) value = value.Substring(0, value.Length -1);
            Directory = value;
        } 
    }
</script>

總結                                                                                                                       

  CodeSmith  最大的優點就是編寫模板生成符合條件的代碼。其IDE自身提供了不少相關的模板,裏面有不少好用的語法糖。附件提供本身編寫的幾個模板,供你們學習參考。

   小夥伴們快快動手編寫屬於本身的模板吧,從繁瑣的任務重脫離出來,咱們的編程更加的愉快。

   下載

相關文章
相關標籤/搜索