我們設計快速ORM框架的程序結構如 圖所示
框架中包含了一個實體類型注冊列表,列表中 包含了實體類型和相應的RecordORMHelper對象。應用程序在使用框架前必須注冊實體類型, 向實體類型注冊列表添加將要操作的實體類型,應用程序注冊實體列表時不會立即導致代碼 的自動生成和編譯。
我們首先定義了一個基礎的抽象類型RecordORMHelper,該類型 定義了處理實體類型和數據庫的映射操作,主要包括從一個System.Data.IDataReader讀取數 據並創建實體類型,為新增,修改和刪除數據庫記錄而初始化System.Data.IDbCommand對象 等等。該類型是快速ORM框架的核心處理對象,數據庫處理模塊將使用RecordORMHelper來作 為統一的接口來處理實體類和數據庫的映射操作。
代碼生成器分析實體類型列表中所 有沒有處理的實體類型,獲得其中的使用BindTableAttribute和BindFIEldAttribute特性保 存的對象和數據庫的映射關系,針對每一個實體類型創建一個Class的代碼,該Class是從 RecordORMHelper上派生的,並實現了RecordORMHelper預留的接口。代碼生成器可以同時為 多個實體類型創建C#源代碼,此時一份C#源代碼中包含了多個從RecordORMHelper派生的 Class類。
C#代碼編譯器接受代碼生成器生成的代碼,進行編譯生成一個臨時程序集 ,該程序集中就包含了多個派生自RecordORMHelper的類型,每一個類型都專門處理某種實體 類型。編譯器在編譯程序是需要指定所引用的其他程序集,這裡包括 mscorlib.dll, System.dll和System.Data.dll,此外還包括類型RecordORMHelper所在的程序集,也就是包 括快速ORM框架的程序集,這裡的程序集不一定是DLL格式,也可能是EXE格式。於是我們編譯 程序時引用了一個EXE,這種操作在使用VS.NET等開發工具時是禁止的。從這裡可以看出,一 些使用VS.NET開發工具所不可能實現的功能我們可以編程使用.Net框架來實現。
.NET 框架自己包含了一個C#代碼編譯器,它的文件名是CSC.EXE,在.NET框架的安裝目錄下,在筆 者的電腦中其路徑是 C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe 或者 C:\Windows\Microsoft.Net\Framework\v2.0.50727\csc.exe ,它是一個基於命令行的編輯 器,能將C#代碼編譯生成EXE或者DLL文件。關於C#代碼編譯器可參考MSDN中的相關說明。
快速ORM框架的控制模塊接受應用程序的請求,首先檢查實體類型注冊列表,若列表 中沒有找到相應的RecordORMHelper對象,則調用代碼生成器生成代碼,然後調用C#代碼編譯 器編譯生成臨時的程序集,然後加載臨時程序集,使用反射(調用 System.Reflection.Assembly.GetType函數)找到其中所有的的RecordORMHelper類型,然後 根據類型動態的創建對象實例,並填充到實體類型注冊列表。最後調用RecordORMHelper預定 的接口來實現ORM功能。
若我們在使用快速ORM框架前,將所有可能要用到的實體對象 類型添加到實體類型注冊列表中,則快速ORM框架會生成一個臨時程序集,但我們是陸陸續續 的往ORM框架注冊實體對象類型,則快速ORM框架內部可能會多次調用代碼生成器和代碼編譯 器來生成臨時程序集,這樣最後會生成多個臨時程序集。一般的建議在使用框架前將向ORM框 架注冊所有可能用到的實體對象類型,這樣框架只會執行一次動態編譯的操作。