領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多對於 Spring.NET 來說,這是相當不平凡的一年。在12月的 GA 釋出之前,我們經歷了兩個里程碑版本和兩個候選釋出版本。1.1 版本的第一個程式碼塊可以追溯到2004年末,當時 Aleks Seovic 開始著手 ASP.NET 框架。總之,這是一個漫長的過程。歲末之際,是回顧過去和現在的自然時機,我想感謝專案其他成員和 Spring.NET 社群的所有貢獻和支援。我期待著激動人心的2008年!
Spring.NET 1.1 的功能集相當廣泛。包括一個用於依賴注入的 IoC 容器、AOP、ASP.NET 框架、宣告式事務管理以及更多。然而,要提高程式碼結構和可測試性,最具價效比的方法是將依賴注入和 AOP 加入您的開發工具箱。依賴注入是這兩種技術中更基礎的一種,我想就配置 Spring.NET 容器的選項提供一些額外的資訊。
顯然,配置容器最常見的方式是透過 XML。XML 雖然提供了極大的靈活性,但也很冗長,每個人都會在酒席上抱怨 XML 配置檔案(無論是 Spring 的還是其他的)有多麼令人討厭。編寫自定義可以極大地減少冗餘,去除許多樣板 XML,並呈現專注於特定領域的屬性。例如,Spring.NET 為事務管理和 AOP 配置提供了此功能。不過,關於非 XML 配置的好訊息是,Spring.NET 將在其下一個版本中新增基於屬性的 DI 和對程式集中的帶註解類的自動檢測。正如您可能預期的那樣,所提供的功能將與 Spring Java 中的功能相當相似(參見此處和此處),但會仔細調整以去除多餘的 Java 偽影(如 JSR-250 屬性),並引入僅在 .NET 中有意義的新功能(如利用方法引數名稱進行按名稱裝配)。
需要記住的一點是,核心容器不依賴於基於 XML 的物件定義。容器有自己的內部物件模型用於這些定義。因此,物件定義可以來自多種格式。據我所讀到的,特別吸引人的是使用 DSL 工具包配置異常處理建議。其他有趣的配置方法是使用指令碼語言 DSL(請參閱這篇關於 Spring Java + Groovy 整合的帖子)。歸根結底,目標是讓您可以根據手頭的任務在多種配置方法中進行選擇。
在當前版本中,有幾個關於容器的程式設計控制和配置的功能似乎並不廣為人知。以下是對這些功能的簡要概述。我很快會在參考文件中提供更完整的描述。
主要的 IoC 容器介面,IApplicationContext包含方法
根據與該名稱關聯的物件定義,容器將對傳入的例項執行依賴注入。當您需要在執行時響應使用者請求來建立物件時,這尤其有用。在這種情況下,您通常會將一些對該情況獨特的資料傳遞給建構函式,然後讓容器配置所有使用者請求通用的其餘物件依賴項。
此功能定義在的子介面上IApplicationContext,即IConfigurableApplicationContext。呼叫程式碼如下所示:
((IConfigurableApplicationContext) applicationContext).ObjectFactory.RegisterSingleton("ObjectB", myObjectBInstance);
已註冊的物件不會被修改;它只是原樣儲存在提供的名稱下。但是,其他物件可能會將此註冊物件引用為依賴項。
按名稱檢索物件很簡單
object o = applicationContext.GetObject("AccountManager")
然後轉換為適當的型別。您也可以按型別請求物件
IDictionary dict = context.GetObjectsOfType(typeof (IAccountManager));
這些 API 呼叫需要一些 TLC,將它們變得通用,並提供一個方便的方法來獲取指定型別的單個物件,而不是集合。
類GenericApplicationContext是一個不假定任何特定物件定義格式的 IoC 容器。您可以像這樣用嵌入式資源中的基於 XML 的物件定義來載入它:
GenericApplicationContext ctx = new GenericApplicationContext();
IObjectDefinitionReader objectDefinitionReader = new XmlObjectDefinitionReader(ctx); objectDefinitionReader.LoadObjectDefinitions("assembly://MovieFinder/AppContextContribution.xml");
然後,您可以使用以下方式構建的其他物件定義新增到上下文中:ObjectDefinitionBuilder. ObjectDefinitionBuilder提供了一個簡單的流暢介面,用於簡化物件定義的建立。因此,ObjectDefinitionBuilder允許您將方法呼叫連結在一起,以建立與您在 Spring XML 中熟悉的元素大致對應的物件定義。
IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory();
ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, typeof(ColonDelimitedMovieFinder));
builder.AddConstructorArg("movies.txt") .SetLazyInit(true);
ctx.RegisterObjectDefinition("AnotherMovieFinder", builder.ObjectDefinition); // process object definitions… ctx.Refresh()
此程式碼摘自更新的“MovieFinder”示例,您可以從 nightly builds 中下載。順便說一句,IObjectDefinitionFactory有另一個實現,WebObjectDefinitionFactory,用於 ASP.NET 頁面和使用者控制元件,儘管您在這種情況下不太可能使用它。
這裡有一個額外的示例,使用TestObject類,它展示了更多的ObjectDefinitionBuilderAPI。
ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, typeof (TestObject));
builder.AddPropertyValue("Age", 22) .AddPropertyValue("Name", "Joe") .AddPropertyReference("Spouse", "Spouse") .SetSingleton(false);
ctx.RegisterObjectDefinition("TestObject", builder.ObjectDefinition);
builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, typeof(TestObject));
IList friends = new ArrayList(); friends.Add(new TestObject("Dan", 34)); friends.Add(new TestObject("Mary", 33));
builder.AddPropertyValue("Friends", friends) .AddConstructorArg("Susan") .AddConstructorArg(23) .SetSingleton(false);
ctx.RegisterObjectDefinition("Spouse", builder.ObjectDefinition);
如果您已經有一個基於 XML 的應用程式上下文,您可以將其傳遞給建構函式,GenericApplicationContext,這意味著它將在後者的父應用程式上下文中作為簡單的根/子層次結構存在。您還可以將上下文與ContextRegistry在一個名稱下注冊,以提供服務定位器風格的查詢。
目前,ObjectDefinitionBuilderAPI 相當“字串化”,這意味著雖然可以註冊物件進行“按型別”裝配,但比它需要的使用起來更冗長。改進此 API 的“流暢性”是未來版本中另一個需要改進的領域。
好了,各位,今天就到這裡。新年快樂!