对使用CodeSmith模板生成NHibernate的代码的分析
?????? CodeSmith是我們常用的代碼生成工具,其跟據(jù)不同的模板生成不同代碼的方式能大大加快我們的項(xiàng)目開發(fā),減少重復(fù)勞動(dòng)。NHibernate模板就是其常用模板之一。從這里可以下載到最新的模板文件。現(xiàn)在最新的版本為NHibernate-v1.2.1.2125,可以生成NHibernate1.2,2.1,3.0的代碼。我下載的稍早,是NHibernate-v1.1.7.2056,最高生成2.1的代碼,不過(guò)大同小異,就以我下載的版本來(lái)進(jìn)行分析吧。
?
? ? ? 基本生成操作就不說(shuō)了,官網(wǎng)上有講解的視頻,也有大把的網(wǎng)友做了專門的教程。代碼生成后,主要分為五大塊:
????? 1.Base塊,也就是基類塊,這里放有BusinessObjects塊,ManagerObjects塊,UnitTests塊的基類,還包括一個(gè)作者提供我們的一個(gè)管理NH的ISession的小模塊:NHibernateSessionManage塊。
? ? ? 2.BusinessObjects塊,也就是我們常說(shuō)的實(shí)體(Entity/Model)塊。里面放置著與數(shù)據(jù)庫(kù)表一一對(duì)應(yīng)的各個(gè)實(shí)體。
? ? ? 3.HbmMaps塊,NH必用,不多講。
? ? ? 4.ManagerObjects塊,也就是我們常說(shuō)的BL層,里面包括了對(duì)每個(gè)實(shí)體的操作類,命名方式類似于XXXManage等等。另外還有一個(gè)小工廠,通過(guò)不同的方法實(shí)例化不同的管理類,比較簡(jiǎn)單,不表。
? ? ? 5.UnitTests塊,測(cè)試用例塊,這不是我們今天談的重點(diǎn),故不多述。
?
? ? ? 從上面可以看到,NH模板生成的代碼是典型的三層架構(gòu)式代碼,采用的架構(gòu)模式是活動(dòng)記錄式。 更詳細(xì)的概念描述請(qǐng)自行Google,或者參見(jiàn)我另兩遍博文:業(yè)務(wù)邏輯架構(gòu)模式(事務(wù)腳本,表模塊,活動(dòng)記錄,領(lǐng)域模型),再談業(yè)務(wù)邏輯架構(gòu)模式(事務(wù)腳本,表模塊,活動(dòng)記錄,領(lǐng)域模型)。
? ? ? 由于Base塊里面的基類與下面三塊里的子類的關(guān)系較大,所以我將按照BusinessObjects塊,ManagerObjects塊,NHibernateSessionManage塊的順序來(lái)講述,在講述的過(guò)程中直接將基類一起表述。例子就參見(jiàn)下面的一張圖,其中Aim是實(shí)體類,AimManage是其對(duì)應(yīng)的管理類。
? ? ??
? ? ? 首先是BusinessObjects塊,其實(shí)我們更常見(jiàn)的叫法是實(shí)體層。Aim是我們自己的實(shí)體,BusinessBase<T>是其基類,其中T這個(gè)泛型是指主鍵的類型,如果是聯(lián)合主鍵,這里則不會(huì)是基本類型,而是會(huì)單獨(dú)生成一個(gè)類,這個(gè)類的屬性與聯(lián)合主鍵的每一個(gè)子元素一一對(duì)應(yīng)。BusinessBase<T>實(shí)現(xiàn)了IBusinessBase<T>接口,在這個(gè)接口里規(guī)定了一個(gè)很重要的屬性:Id,其類型由T來(lái)指定,這表明了所有表的主鍵的在代碼里都叫Id。當(dāng)然,如果實(shí)際的表中的主鍵不叫Id也是沒(méi)有關(guān)系的,實(shí)體的配置文件hbm.xml可以解決這個(gè)問(wèn)題。這個(gè)接口還有兩個(gè)方式:GetHashCode和Equals,比較簡(jiǎn)單,不多表。
?
? ? ? 再來(lái)看ManagerObjects塊,對(duì)于這我們也有更常見(jiàn)的叫法:BL層或者是業(yè)務(wù)邏輯層。
?????
????? 從上向下講,最開始是個(gè)IManagerBase<T, TKey>接口,其中T是指其管理的實(shí)體類別,TKey是其管理的實(shí)體的主鍵類型。在這個(gè)接口中定義了常見(jiàn)的實(shí)體操作方式:增刪改和各種形勢(shì)的通用的查詢。ManagerBase<T, TKey>類則是其具體的實(shí)現(xiàn)。IAimManage是具體實(shí)體管理類的接口,里面定義了具體實(shí)體所具有的特定的操作方法,注意,這里繼承了IManagerBase<T, TKey>接口,這是很重要的一點(diǎn),等下表述。最后是AimManage類,其繼承了ManagerBase<T, TKey>類和IAimManage接口。從前者獲取通用操作的實(shí)體,從后者獲取定義的特定操作并由自己來(lái)實(shí)現(xiàn)。這里就要講為什么IAimManage接口要繼承IManagerBase<T, TKey>。從編譯的角度來(lái)講,前者不繼承后者依然可以通過(guò)編譯,但從我們架構(gòu)代碼的角度來(lái)講,當(dāng)編碼中我們要操作AimManage類時(shí),有兩種方式,一種是直接通過(guò)本類型操作:
AimManage?manage?=?new?AimManage();一種是通過(guò)接口操作:
為了減少代碼耦合,通過(guò)接口操作是比較理想的方式。如果前者不繼承后者,當(dāng)出現(xiàn)后者的代碼時(shí),我們就無(wú)法通過(guò)manage來(lái)操作AimManage類從ManagerBase<T, TKey>類繼承到的通用操作了。換種說(shuō)法,由于ManagerBase<T, TKey>類繼承并實(shí)現(xiàn)了IManagerBase<T, TKey>接口,AimManage類又繼承了ManagerBase<T, TKey>類,那么實(shí)際上AimManage類間接繼承并實(shí)現(xiàn)了IManagerBase<T, TKey>接口。現(xiàn)在AimManage類又繼承并實(shí)現(xiàn)了IAimManage接口,從多繼承的角度來(lái)講,各個(gè)接口只能操作其子類從本接口繼承而來(lái)的屬性與方法,如下圖:
?
如果IAimManage接口沒(méi)有繼承IManagerBase接口,那當(dāng)代碼是這么寫的時(shí)候:
IAimManage?manage?=?new?AimManage();?變量manage是無(wú)法執(zhí)行A()方法的,因?yàn)锳()方法從IManagerBase接口而來(lái)。
?
? ? ? 最后看看NHibernateSessionManage塊,這是作者為我們提供的一個(gè)Session管理模塊,包括兩個(gè)類與兩個(gè)接口。這個(gè)模塊通過(guò)接口的方式與其它模塊交互的少,故不多表,主要講講兩個(gè)類的使用:NHibernateSessionManager類與NHibernateSession類。NHibernateSession類是作者為我們重新封裝的Session類,他將始的ISession接口封裝了進(jìn)去,目的是代替NH原始的ISession接口。里面有兩個(gè)重要的成員ISession和ITransaction。其中ISession就是NH的原始的ISession接口。由于他在這里將原始的ISession接口封裝了進(jìn)去,通過(guò)其操作事務(wù)就不是很方便,于是作者就使用成員ITransaction將ISession內(nèi)的ITransaction引用出來(lái),并寫了一大堆方法來(lái)完成對(duì)事務(wù)的操作。還有一個(gè)方法:GetISession()來(lái)獲取原始的ISession。
?
????? NHibernateSessionManager類是具體的Session管理類。他通過(guò)靜態(tài)變量Instance實(shí)現(xiàn)了單例模式。他有一個(gè)重要的屬性Session和一個(gè)重要的方法CreateISession()。通過(guò)Session屬性來(lái)獲取本次操作的NHibernateSession類。可以看到,作者將每次操作的NHibernateSession放到了緩存中(webForm與winForm放置的地方不同),提高了性能。CreateISession()方法則是真正獲取原始ISession的方法,NHibernateSession類的GetISession()方法調(diào)用的也是他。
public?ISession?GetISession(){
????if?(iSession?==?null)
????????iSession?=?NHibernateSessionManager.Instance.CreateISession();
????return?iSession;
}
?????? 回到ManagerBase<T, TKey>類,在其兩個(gè)構(gòu)造函數(shù)中:
public?ManagerBase()????:?this(NHibernateSessionManager.Instance.Session)?{?}
public?ManagerBase(INHibernateSession?session)
{
????this.session?=?session;
????this.session.IncrementRefCount();
}
?????? 默認(rèn)就是調(diào)用NHibernateSessionManager類單例實(shí)例的Session屬性,或者通過(guò)自定義INHibernateSession來(lái)注入。
?
? ? ? 以上就是代碼分析的全過(guò)程,可以看出,生成的代碼精干緊湊,使用方便,是我們學(xué)習(xí)三層架構(gòu)模式,活動(dòng)記錄模式和生產(chǎn)實(shí)踐的良好示范。
轉(zhuǎn)載于:https://www.cnblogs.com/ljzforever/archive/2011/03/14/1983121.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的对使用CodeSmith模板生成NHibernate的代码的分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 基于Response的将数据导出到Exc
- 下一篇: cmd 终端快速查看自己的ip地址