領先一步
VMware 提供培訓和認證,助力您的職業發展。
瞭解更多對於 Spring.NET 來說,這是非凡的一年。我們在12月正式釋出之前經歷了兩個里程碑版本和兩個候選版本。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,包含方法 ConfigureObject(object objectToConfigure, string objectDefnitionName)
基於與名稱關聯的物件定義,容器將對傳入的例項執行依賴注入。當您需要執行時建立物件以響應使用者請求時,這特別有用。在這種情況下,您通常會向建構函式傳入一些特定於當前情況的資料,然後讓容器配置物件中對所有使用者請求都通用的其餘依賴項。
此功能在 IApplicationContext
的一個子介面上定義,即IApplicationContext,即IConfigurableApplicationContext。呼叫程式碼如下所示
((IConfigurableApplicationContext) applicationContext).ObjectFactory.RegisterSingleton("ObjectB", myObjectBInstance);
註冊的物件不會被修改;它只是按原樣儲存在提供的名稱下。但是,其他物件可以引用此註冊物件作為依賴項。
按名稱檢索物件很簡單
object o = applicationContext.GetObject("AccountManager")
然後轉換為適當的型別。您也可以按型別獲取物件
IDictionary dict = context.GetObjectsOfType(typeof (IAccountManager));
這些 API 呼叫需要一些改進,使其泛型化,並提供一個便捷方法來獲取指定型別的單個物件,而不是集合。
類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); // 處理物件定義… ctx.Refresh()
這段程式碼取自更新後的“MovieFinder”示例,您可以從每晚構建中下載。另外提一下,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
的建構函式,這意味著它將在簡單的根/子層次結構中充當後者的父應用程式上下文。您還可以使用GenericApplicationContext,這意味著它將在簡單的根/子層級結構中作用於後者的父級應用上下文。你也可以將該上下文註冊到ContextRegistry下,以便提供服務定位器風格的查詢。
目前,ObjectDefinitionBuilderObjectDefinitionBuilder
API 相當“字串化”,這意味著雖然可以註冊物件以便“按型別”注入,但這比實際需要更冗長。改進此 API 的“流暢性”是未來版本中另一個需要改進的領域。
好了,就到這裡了。祝大家新年快樂!