最近一段時間,我利用業余時間在做一個基於客戶公司風格的代碼生成器,這個代碼生成器在之前的文章中稍微介紹過(修改的T4代碼生成器),我並不是白手起家,而是參考了一們園友的作品。原作品的特點:
1:基於WPF。
比起傳統的WinForm來講,wpf在用戶體驗性上有很大的優勢。
優點一:能夠比較容易的實現基於Visual風格的界面。
這讓使用者會比較熟悉,不會花太多時間去了解如何使用。
優點二:自由拖拽UI元素
比如我們非常容易的能夠將一個頁面分割成不同的小塊,然后我們可以自由的拖拽這些小塊到不同的區域。

2:基於T4 text template
其實t4 text template很早以前就出來了,但關注度一直不太高(個人認為)。只不過后來由於微軟的asp.net mvc自身采用了t4,算是一個非常成功的案例,而我們在選擇方案時,往往其中一個比較重要的參考指標就是有沒有成功案例。即然有了微軟的親自實踐,足以說明t4的實用性。
其實我對於工具的選擇,一直保持比較中立的態度,有些開發人員往往抱怨現成的工具不好用,不能滿足自己的需求,一旦現有的功能實現不了,就說軟件不好用。在微軟沒在asp.net mvc上使用t4前,它的熱度一直不高。一旦有人成功的將某種技術在某個項目上成功的應用開來,大家才發現原來此項技術還是不錯的,只是我們自己不知道如何更好的利用它而已。有些時候,我們需要有能力去在別人的基礎上完善功能,以實現自己的需求,而它的前提就是我們需要得到一個開源項目,否則你需要從0開始。
3:它是開源的。
只有項目開源,我才有可能不從0開始繼續我自己的代碼生成器,畢竟一個人從0開始做一件事的難度太大,而且我也不可能有那么多時間從頭開始,更重要的是人無完人,如果有其它的作品已經完成了你原來不太熟悉的功能,豈不是很爽。
好了,講了這么多,我再來分享下,我在原作品基礎上的一種改動及應用t4 templeate時遇到過的一些問題。
缺陷:內存漏泄。
在進行t4生成代碼時,我們可以定義自己的TextTemplatingEngineHost,里面有這樣一個方法
public AppDomain ProvideTemplatingAppDomain( string content)
{
// return AppDomain.CurrentDomain;
CurrentDomain= AppDomain.CreateDomain(DomainName);
return CurrentDomain;
}
:
它是ITextTemplatingEngineHost接口中的一個方法,在微軟提供的示例代碼中在返回AppDomain時也是新創建的,在代碼中有一段注釋的內容,返回當前AppDomain,但發現運行中有些問題,不知道大家的代碼是如何處理這個方法的。
在使用時我們會先new一個Host:TextTemplatingEngineHost host = new TextTemplatingEngineHost(),問題就在於,每new一個Host都會創建一個AppDomail,最后發現每調用一次,內存就會增加(1到3M內存,有一次多執行幾次批處理,內存就上了600M了),最后我就嘗試手動卸載這些新創建的AppDomail,最后問題解決,為了調用方便,我讓TextTemplatingEngineHost實現IDisposable
public void Dispose()
{
if ( null != CurrentDomain)
{
try
{
AppDomain.Unload(CurrentDomain);
}
catch (Exception ex)
{
throw new Exception( " AppDomainUnLoad ERROR! " + ex.ToString());
}
finally
{
CurrentDomain = null;
}
}
}
然后這樣調用:using (TextTemplatingEngineHost host = new TextTemplatingEngineHost()){......}
增強:自動生成edmx。
由於我們公司項目風格問題,我們數據庫訪問方面采用的是Linq to Entity中的 DataBase First,即先設計好數據庫,然后在UI中添加edmx。所以我們的問題就是如何生成edmx文件,當時的問題:
問題一:edmx中有很復雜的關系,我們如果用t4模板來實現,有一定難度。
問題二:每個entity它在UI界面上都有位置關系,及X軸與Y軸數值,這些數值決定了它們在界面上的布局,這些數值是不太好解決的。
解決方案:EdmGen2.exe,這是在EdmGun基礎了封裝出來的,能夠直接生成edmx文件,EdmGen不能直接生成edmx,它只能生成一些源數據文件,比如:csdl,ssdl,msl等。
edmgen2.exe問題:本想直接在程度中調用,但發現傳遞參數時有些問題,在命令窗口中輸入參數時,一般我們用引號將參數包括起來,這樣可以讓程序認為是一個完整的參數,之所以這樣講,是因為大多數的exe的參數是一個string[],它會將輸入的參數以空格分隔成數組,如果我們的參數中包含了空格,就需要用引號包括起來。這種方法直接在命令提示窗口中是沒有問題的,但我們現在是要在應用程序中調用exe,並傳遞參數給它,下面的是錯誤的格式:
用轉義字符:
解決方案:即使edmGen2也是一個開源項目,而且是.net寫的,所以何不直接調用它的方法呢,從而先避免這種參數傳遞。
第一:將edmgen2的代碼添加到工程中。
第二:由於edmgen2是一個exe,所以我們需要將默認的Main方法名稱修改成RunMain,將它識別成一個Helper,而不是一個啟動對象。
第三:直接傳遞string[],而不在傳遞string類型的參數。
SqlConnectionString,
" System.Data.SqlClient ",
NameSpace
};
EdmGen2.RunMain(argsList);
問題:t4 text template轉義字符 "\" 。
比如下面的代碼:
這樣寫,<#=NameSpace.Value#>不會被識別成正確的語法,后來發現寫成這樣是沒問題的:即在<#前面多加一個空格。
問題:雖然此時t4識別了變量,但我們需要做特殊的處理,即在t4生成文本后,我們需要將這些加的空格刪除,因為在一個正常的路徑中多了一個空格是肯定錯誤的。
解決方案:t4 中轉義字符"\",這樣我樣可以這樣寫:我們不必在刪除空格的問題。
這篇比較長了,下篇再寫一些余下的內容:
1:如何生成Project
2:如何生成Sln
3:如何將生成的cs文件引用自動引用動工程中
4:......
