摘 要:Unity是微軟PP推出的一個開源的IOC框架。Unity框架是微軟IOC思想的體現,IOC意味控制反轉。即不創建對象,但是描述創建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件中描述哪一個組件需要哪一項服務。容器負責將這些聯系在一起。其原理是基于OO設計原則的“別找我,我會來找你的”。也就是說,所有的組件都是被動的(Passive),所有的組件初始化和調用都由容器負責。組件處在一個容器當中,由容器負責管理。簡單的來講,就是由容器控制程序之間的關系,而非傳統實現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,這就是反轉。
關鍵詞:Unity;插件模式;管道與上下文模式
中圖分類號:TP393.092 文獻標識碼:A 文章編號:1674-7712 (2014) 14-0000-01
一、Unity的IOC思想
Unity支持構造函數依賴注入和屬性依賴注入,是一個具有IOC思想的框架。提出容器的概念,通過控制反轉,可以將控制權從程序轉向容器。
從GoF設計模式中,我們已經習慣一種思維編程方式:Interface Driven Design接口驅動,接口驅動有很多好處,可以提供不同靈活的子類實現,增加代碼穩定和健壯性等等,但是接口一定是需要實現的,也就是說會出現IServiceA serviceA=new ServiceA();這樣會帶來緊耦合的情況,如果我們想要改變接口的實現,必須修改代碼。而IOC模式可以延緩接口的實現,根據需要實現,有個比喻:接口如同空的模型套,在必要時,需要向模型套注射石膏,這樣才能成為一個模型實體,因此,我們將人為控制接口的實現成為“注射”。此時,我們只需要在代碼中寫IServiceA impl=UnityContainer.Resolve
二、基于RegisterType的Unity設計模式研究——插件模式
當調用RegisterType方法的時候,其實是觸發了容器中的Registering事件,問題是誰訂閱了Registering事件?RegisterType方法內部不做功能的實現,而需要通過Registering事件讓別人去完成。這其實是使用了一種類似插件的設計模式,基類對象UnityContainer定義了Registering事件,同時定義ExtensionContext作為一個聯系上下文的對象,該對象克隆了UnityContainer中的部分屬性及事件,使之成為類似UnityContainer血脈一樣的對象。定義UnityContainerExtension,內部包含了ExtensionContext對象。根據實際的需求可以自定義對象,只要繼承了UnityContainerExtension,就可以使用ExtensionContext中的事件及屬性,做出各自的功能的實現。
那怎么樣才能將這些繼承UnityContainerExtension的插件同容器UnityContainer聯系在一起呢?只需要在UnityContainer中定義AddExtension(ExtensionContext)方法,在項目啟動的時候進行注冊,就可以達到注冊插件的目的。這就好比一輛大型航母,他擁有炮彈口,火槍口,水炮口等多個配置口,但是具體的炮彈裝置,火槍裝置其實就是一個個繼承ExntesionContext的插件,通過插件的注冊,讓其具有高度的作戰力及松耦合性。而extensionContext內部的事件等對象就是實現這一思想的關鍵。
三、基于Resolve的Unity設計模式研究:pipeline+context模式
Unity框架的Resolve方法的定義和實現幾乎和RegisterType方法一樣,也是通過插件的形式,這種方法的優良擴展性已不必多說。Unity的具體實現使用管道+上下文的模式,具體來說就是定義了一個IBuilderStrategy接口,該接口下定義了四個基本方法:(1)void PreBuildUp(IBuilderContext context);(2)void PostBuildUp(IBuilderContext context);(3)void PreTearUp(IBuilderContext context);(4)void PostTearDown(IBuilderContext context)。
IBuilderContext是個上下文對象,類似于上文中插件模式中的ExtensionContext。在實現的時候,定義多個實現于IBuilderStrategy接口的策略。可以任意地組合這些策略的執行順序,由總的策略管理器決定執行方式,最終達到在容器中解析實例的目的。
可以用一個生動的例子去形容這個處理流程,比如有一個為居民提供飲用水的自來水廠,它的任務就是抽取自然水源,進行必要的凈化處理,最終輸送到居民區。凈化處理的流程可能是這樣的:天然水源被汲取到一個蓄水池中先進行雜質的過濾(我們稱這個池為過濾池);被過濾后的水流到第二個池子中進行消毒處理(我們稱這個池為消毒池);被消毒處理的水流到第三個池子中進行水質軟化處理(我們稱這個池為軟化池);最終水通過自來水管道流到居民的家中。”
四、結束語
Unity框架的實現采用了諸如上述的“插件模式”和“管道與上下文模式”。整體的框架采用的是依賴注入,控制反轉的思想。依賴注入的好處在于增加了模塊的重用的靈活性。通過配置在容器中注冊,而不是在代碼中的緊耦合,實現的解耦,易擴展的目的。
參考文獻:
[1]蔣金楠.你知道Unity IoC Container是如何創建對象的嗎[OL].2011(01).
[2]弗里曼.Head First設計模式[M].北京:中國電力出版社,2007.
[作者簡介]胡文琪(1987-),男,上海人,同濟大學軟件學院,高級軟件工程師,本科,研究方向:軟件架構與設計模式、asp.net,db。