1、簡介:
Elite Container是DELPHI下的一個輕量級IoC對象容器(IoC:Inverse of Control,反轉控制)。它是參考了Java中的Spring框架(主要是配置文件的寫法),並結合DELPHI的特色來構建的。相比Spring的對象容器,它提供的功能更爲精簡經常使用(如對象延遲建立、對象屬性自動注入等),下降了學習的難度,而且提供了不少擴展點,你只需簡單地寫一個插件實現類,並在配置文件中進行簡單配置,就可讓Elite Container擁有你的自定義功能!
Elite Container主要擁有如下的一些特性:
一、不管使用或不使用BPL,均可以用Elite Container來構建你的程序(但不建議用純DLL,由於各DLL中,同一個類的類型信息是不一樣的,不熟悉相關知識的話,有可能會帶來一些問題,而這自己並非Elite Container的問題)
二、支持多種屬性注入類型,如直接值、枚舉、集合、StringList、ObjectList等。其中StringList這種注入方式,在解決鍵值對配置時很是有用,詳細請參看相關例子
三、支持構造函數注入。但因爲Delphi的元信息不夠完備,有時須要寫一個構造函數調用類(寫法很簡單),纔可以讓容器正確調用該類和其子類的構造函數,詳細請看相關例子另外因爲構造函數注入有可能會引發循環注入的問題,所以建議儘可能使用屬性注入來表達對象的依賴關係,不得已的時候才使用構造函數注入
四、支持對象配置的繼承。省去配置子對象時,又要把父對象的屬性配置從新拷貝一遍,既麻煩又難維護。
五、支持對象屬性的自動注入。若是你的屬性命名知足必定規則,即可以利用自動注入來省去大量的配置書寫
六、支持配置文件的引入,提升配置文件的可重用性
七、支持多種對象的生命週期配置(對於無狀態的管理類,如邏輯層,單例生命週期是最經常使用的)
八、支持對象的別名配置
九、加強的對象註冊機制,可註冊非TPersistent爲基類的類(常見的如TInterfacedObject),而且容器能夠區分不一樣單元的同名類
十、兼容使用Delphi的RegisterClass來註冊類的遺留模塊
十一、大量的自定義插件擴展點。你能夠自定義本身的屬性注入配置方式、構造函數注入配置方式、對象配置引入方式、對象生命週期管理方式、對象屬性自動注入方式等
十二、支持對象的延遲建立。以避免容器初始化時,會自動實例化一些須要花費大量時間來建立,而又不多用的類。
1三、大量的可編程接口。你甚至能夠本身寫一個用INI、或數據庫來進行配置的IoC容器!
藉助Elite Container和Ioc思想,你能夠更輕易地構建出具備鬆散耦合、重用度高的應用程序。它的核心思想就是拆分功能的接口和實現,上層只依賴於下層的接口,而後經過Elite Container的配置,把不一樣的實現類注入到該接口中,達到更換功能,也就是複用已有代碼的目的。設計人員能夠真正地發揮好本身的面向對象思想和相關設計模式,來架構企業級的應用程序,而無需象之前那樣,在Delphi中用起面向對象總有點捉襟見袖的感受。
DEMO下載地址:http://download.csdn.net/source/1891434數據庫
2、使用Elite Container的典型開發步驟:
一、新建項目,在項目選項中選擇「build with runtime packages」,去掉全部的默認包,而後選擇EliteContainerD7
二、創建應用程序的領域(如對象實體、邏輯處理、接口服務等)
三、用XML文件來配置這些對象
四、引用elXMLConfigurateContainer單元,聲明一個IelObjectContainer類型的接口變量
五、給這個接口建立一個TelXMLConfigurateContainer的實例,把這個XML文件的路徑(相對或絕對路徑都可,構造函數有參數指定),做爲參數傳入到構造函數中
六、TelXMLConfigurateContainer建立的時候,會自動初始化生命週期配置爲"singleton",而且不是延遲建立的對象
七、如今能夠根據配置文件所配置的對象ID或別名,從容器中獲取已配置好的對象或接口了
八、調用所獲取的對象或接口,來完成程序的功能編程
3、DEMO目錄說明:
Bin 各個例子的可執行程序
Bin\Config 各個例子所用到的配置文件
Lib 各個例子用到的dcp文件,須要在項目設置的"Build with runtime packages"中引入
Source 各個例子的源代碼。共26個例子,用於詳細介紹Elite Container的特性。請務必結合源代碼、配置文件和可執行文件來理解,這樣才能達到演示的目的。若是要編譯例子源代碼的話,請把Lib目錄添加到Delphi的Library Path下,並修改下項目的輸出路徑。設計模式
4、DEMO簡要說明:
例1:示範了容器最基本的功能。如何獲取一個配置好的對象,包括以對象形式獲取(GetObj),和以接口的形式獲取(GetIntf)。
例2:示範了容器最基本的功能。與例1不一樣的是,這個例子中,類被封裝了在BPL當中。這種方式是項目實際開發時,最經常使用的方式(以便重用業務邏輯)。注意在配置對象的時候,對象的class配置,還要加上類所在的bpl文件,而後還要在程序中對類進行註冊。
例3:示範瞭如何把直接值(字符串、整數等)注入到屬性中。這種方式經常使用於利用配置來改變對象的某些初始狀態,例如能夠把數據庫連接串以這種方式注入到對象中,以便不用從新編譯也能改變程序的數據庫連接。
例4:示範瞭如何把枚舉或集合注入到屬性中。強大的是,配置中,你既能夠寫枚舉的字符串名稱,也能夠寫枚舉的整數值。
例5:示範瞭如何把其它配置的對象注入到屬性中。屬性能夠是對象類型,也能夠是接口類型(假如被注入的對象,實現了該接口)。這是最經常使用的注入方式,例如把數據訪問對象注入到業務邏輯對象中,以便讓業務邏輯對象訪問數據庫。
例6:示範瞭如何配置一個StringList對象,並把它注入到屬性中。從配置文件中能夠看到,配置的方式很是多。其中KeyValueList和ObjectRefList這兩個屬性的配置都採用類鍵值對的形式,這種形式在解決映射關係時,是很經常使用的。
例7:示範瞭如何配置一個ObjectList對象,並把它注入到屬性中。注意,ObjectList的OwnsObject參數是默認被設置爲false的,也就是說,釋放這個ObjectList,不會釋放裏面的對象。由於Elite Container的單例聲明週期是最經常使用的,所以對象的生命週期應由容器來管理,不該該在ObjectList釋放的時候就釋放。不過也能夠直接把ObjectList配置成管理生命週期,例如它裏面的對象的生命週期被配置了爲"prototype"的時候。你須要清楚地知道對象的生命週期是如何被管理的,纔可正確使用好這種注入方式。
例8:示範瞭如何配置一個InterfaceList對象,並把它注入到屬性中。
例9:示範了對象屬性自動注入的功能。能夠設置爲根據屬性名稱("T"加上屬性名來做爲對象ID)、屬性類型或自動模式,來嘗試從容器中獲取對象。自動注入會做用於沒有手動配置,不是隻讀,類型是對象或接口的那些屬性上。自動注入默認是關閉的(值爲"false"),而按屬性名稱,是最經常使用的自動注入模式。
例10:示範了繼承父對象的屬性配置。纔可以配置文件能夠看到,TMyObjectB的Count、Text、Day這三個屬性的值,均繼承了TMyObjectA中的設置。強大的是,你還能進行屬性配置的覆蓋,能夠看到TMyObjectB中Day的值是wdTuesday,而不是TMyObjectA中配置的wdMonday。
例11:示範了構造函數注入。注意要配置構造函數參數的類型,常見的取值有string、integer、float、boolean、string、enum、set、object、interface等。
例12:示範了對象配置的引入。一般咱們能夠給各個組件寫獨立的配置文件,而後主程序引入這幾個組件的配置文件便可。這樣便重用了組件的配置文件了。注意,若是對象的配置量很是巨大,能夠經過設置lazy="true"來延遲載入該配置文件。
例13:示範了對象的生命週期配置。默認的三種生命週期是:單例"singleton",該對象的實例由容器來管理(不要本身釋放掉它),而且每次獲取都是獲得同一個實例,這種生命週期是默認的生命週期;原型"prototype",容器只負責對象的建立,而不負責實例的釋放,你須要本身來管理它的生命週期;線程單例"per-thread",本質也是單例模式,可是每條線程裏都會有一個不一樣的單例。
例14:示範了對象的別名聲明。此功能經常使用於整合資源,例如幾個組件分別聲明瞭數據庫連接的對象ID,我能夠經過聲明別名,把這幾個數據庫連接的對象ID都指向同一個對象,那麼就實現了幾個組件用同一個數據庫連接了。
例15:示範了完成注入後,讓對象進行初始化處理。一般能夠在這裏檢查對象的屬性有被注入,由於寫漏配置的現象有時仍是難以免的。
例16:示範瞭如何兼容使用RegisterClass來註冊類的老模塊。其實使用上是徹底同樣的,沒任何特殊之處。
例17(進階功能):示範瞭如何注入DELPHI自帶的類。要注意的是,要手動對這些類進行下注冊,其它就沒什麼特殊了。
例18(進階功能):示範瞭如何獲取不一樣單元中的同名類。配置中,class注意要加上類所在的單元名。
例19(進階功能):示範了自定義屬性注入的處理。你須要分別寫一個屬性值識別器和屬性值注入器,而後把它在配置中進行配置便可。能夠看到,例子的配置中,屬性出現了自定義的類型"path"。
例20(進階功能):示範了自定義構造函數注入的處理。你須要分別寫一個構造函數參數值識別器和構造函數參數值注入器,而後把它在配置中進行配置便可。能夠看到,例子的配置中,構造函數參數出現了自定義的類型"owner-selector"。
例21(進階功能):示範瞭如何自定義對象配置引入機制。例子中把對象的配置封裝在了DLL中,對配置起到了簡單的保護做用。由於Delphi被大量使用在客戶端程序中,這跟Java是有區別的。所以這能夠說是具備Delphi特點的一個頗有用的擴展點。
例22(進階功能):示範了自定義對象的生命週期管理方式。
例23(進階功能):示範了自定義的對象屬性自動注入器的編寫。
例24(進階功能):示範瞭如何寫構造函數調用器。當出現如下兩種狀況時,你才須要爲類寫一個構造函數調用器:基類的構造函數不是虛函數,而你在子類中又聲明瞭該構造函數;基類的構造函數雖然是虛函數,可是在子類中,你對它進行了從新聲明,或者提供了重載的版本。通常調用器的邏輯,須要檢查參數的個數、簽名,根據重載的版本,判斷參數是否存在,參數類型是否正確等。
例25(進階功能):示範了對象屬性的延遲獲取。例子中獲取TExample時,三個屬性均是沒值的,只有在它們被訪問到的時候,才用容器中獲取所配置的對象。這樣便大大增長了TExample的獲取速度(這三個屬性所配置的類,爲了演示須要,在建立時都人工sleep了一段時間做爲延遲)
例26(進階功能):示範瞭如何註冊不是TPersistent做爲基類的類。架構
5、其它說明:
Elite Container可支持Delphi 7以上的任何版本,目前暫只提供D7的版本供試用。另外放出此DEMO,主要的目的是爲了能及時收集你們的反饋意見而已,容器自己不能夠避免尚會存在一些問題,如內存泄露、缺少線程保護等,暫時請勿用於實際項目中,不然後果自負。框架