CodeSmith技術原理初探.
初次聽說CodeSmith是在一篇叫做<每個開發人員現在應該下載的十種必備工具>的文章,起初CodeSmith給我的印象不是吸引人.也是在去年的某一段相對比較閒置時候,抽空嘗試了一下CodeSmith,才發現CodeSmith確實是一個好東西.使用過CodeSmith之後,才發現它的實現原理其實不是很複雜,它從Asp.Net的文法中借鑒了不少,應該說CodeSmith實現了Asp.net一部分功能(從aspx模板產生html指令碼)的偽Asp.net,只是CodeSmith額外提供了屬性申明的功能.以下是對CodeSmith實現原理的簡略概述:
1/ 支援執行代碼塊文法 ,與 Asp.net文法一模一樣
2/ 支援內聯運算式文法 ,與 Asp.net文法一模一樣
3/ 支援Code Behind功能(,與 Asp.net的()類似
4/ 支援 函數代碼塊功能, 與Asp.net的函數代碼塊功能 類似
5/ 支援屬性申明,用於配置模板的屬性. Asp.net文法不支援.
關於CodeSmith如何通過模板產生代碼的問題, 我們只要瞭解一下Asp.net如何通過Aspx檔案產生Html指令碼的過程就可以明了.其實Asp.net產生Html指令碼過程遠比CodeSmith複雜的多,因為Asp.net還要呈現ServerControl的Html指令碼.而CodeSmith只專註於 "執行代碼塊" "內聯運算式" " 函數代碼塊"的文法分析及轉換. 該文法分析的邏輯也相對簡單(和Asp.net一模一樣),具體過程如下:
1/ 產生一個類Class1(以模板檔案名稱作為類名),預設從CodeTemplate類繼承,如果有Code Behind,那麼就從Code Behind標記的父類繼承(該父類必須從CodeTemplate類繼承)
2/ 根據所申明的屬性,在Class1中添加相應的屬性申明及成員變數代碼
3/ 把模板檔案中的 函數代碼塊中的函數體 原封不動的拷貝到Class1中,作為Class1的成員函數
4/ 開始產生Class1的核心函數體:__RenderMethod1(System.IO.TextWriter writer, CodeSmith.Engine.Control control),按順序把模板檔案中的執行代碼塊中的代碼塊(不包括字元'')原封不動的移植到__RenderMethod1中,把模板檔案中不屬於執行代碼塊 及內聯運算式的Code轉換成writer.Write("Code");把模板檔案中的內聯運算式的運算式expression轉換成writer.Write(expression).
5/ 編譯所產生的類Class1
6/ 調用類Class1的__RenderMethod1函數,產生實際代碼(就好像Asp.net中,Asp.net的運行架構對於每個Request,都產生Html指令碼).
通過以上分析,大家就覺得CodeSmith的實現原理相對比較簡單,和Asp.net的產生Html指令碼的原理基本一致(大家可以比較一下CodeSmith產生的Compiled Source和Asp.net的Page Compilation Source). 到此位置, 就有人會想,如果沒有CodeSmith,可否通過Asp.net代替CodeSmith來使用?當然答案是完全肯定的.只是CodeSmith帶給我們比較多的便利(比如訪問DBSchema功能函數,屬性值設定等等,直接編譯並產生Code),而使用Asp.net作為代碼產生器相對比較複雜(起碼要建立一個Web虛擬目錄,設計一個Aspx模板檔案,用IE請求獲得asp.net產生的HTML指令碼)並且還要添加一些類似CodeSmith擴充功能,工作量也是不小的,有興趣的朋友可以嘗試一下.
另外補充說明一下在CodeSmith2.6版本中, 編譯錯誤的錯誤碼行數是指Compiled Source的行數,而不是指原來的模板檔案中的行數, 在CodeSmith 3.0中已經是指向原來的模板檔案中的行數(這點已經和Asp.net的Page Compilation Source一模一樣了, 通過預先處理命令:#line實現的 )
一些好的CodeSmith的模板檔案可以從http://www.ericjsmith.net/codesmith/forum/default.aspx?f=16&p=1&ord=vd下載...
共用自動產生DTO/DataAccess/BizObject的CodeSmith模板
如果你有什麼代碼模板,可以與我們共用嗎,我打算搞一個CodeSmith模板共用的團隊,共用我們的模板(CodeSmith論壇上已經有很多了)。
只要你點擊一下按鈕,DTO對象及其集合類、資料訪問類、業務層類的部分代碼自動產生,形成Model、DataAccess、Biz三個目錄,並產生相應的各個類檔案。
MyTemplates.rar
前提:
1、建立資料庫的各個表,最好以複數形式給表命名。
2、設定表的主鍵。
3、設定表的外鍵。
4、建立表的索引。
主要特點:
1、支援一對多和多對一關聯性。
2、支援like查詢。
用法:
1、完成"前提"中提到的各步。
2、用AllStoredProcedures.cst產生所有預存程序
3、用Model/Bulk.cst產生所有檔案
不足:
1、剛建立,還沒來的及詳細測試。
2、模板裡的ModelObject.cst還沒有用
3、BizObject.cst還沒有發布。
(裡面雖然有製作自己的EnterpriseLibrary應用程式塊的模板但沒有內容,過段時間在給出)
大家有什麼好的架構,我可以幫著建立模板,同時希望對我建立的這個模板提出更多的意見。