NET反射工廠方法
資料提供者應用程式接口DataProvider不僅是抽象資料庫通路基類同時也是執行個體化具體資料庫的工廠。它提供了執行個體化具體資料庫通路對象的工廠方法。DataProvider中的工廠方法是靜态過程Static viod CreateProvider()。這個工廠方法調用反射類中的CreateObject函數動态的生成執行個體對象。CreateObject有如下兩種重載形式:
1.DotNetNuke.Framework.Reflection.CreateObject(“data”);
2.DotNetNuke.Framework.Reflection.CreateObject(“data”,”Cross.DNN.Modules.CrossArticle.Data”, “Cross.DNN.Modules.CrossArticle”));
實作反射的關鍵是要提供所要建立執行個體的類型名稱。類型名稱(TypeName)由兩部分組成,第一部分是包含了完整名稱空間(namespace)的類名,第二部分是類所在的元件(Assembly)的名稱。上面的兩種重載形式對應着兩種獲得類型名稱的方法。
由于采用反射技術在運作時才知道要所要執行個體化的相關資訊,是以這些資訊不可以固化在程式中。DNN所采用的是在配置檔案(web.config)中定義了資料提供者應用程式接口實作的配置資訊,并提取這些資訊到相應的類中。配置檔案中針對不同的提供者模式定義了相應的節(section),如資料提供者模式所對應的節就是”data”。以下呈現的就是配置檔案中”data”節的相關資訊:
1.Section Handle:<section name=”data” type=”DotNetNuke.Framework.Providers.ProviderConfigurationHandler, DotNetNuke” />;
2.Section:
<data defaultProvider=”SqlDataProvider”>
<providers>
<clear />
<add name=”SqlDataProvider” type=”DotNetNuke.Data.SqlDataProvider, DotNetNuke.SqlDataProvider” connectionStringName=”SiteSqlServer” upgradeConnectionString=”” providerPath=”~/Providers/DataProviders/SqlDataProvider/” objectQualifier=”” databaseOwner=”dbo” />
</providers>
</data>
Section Handle的作用一是标明了具體配置節(section)的名稱;二是在type屬性中提供了提取配置資訊對象的類型名稱,即位于DotNetNuke.Framework.Providers 名稱空間下的ProviderConfigurationHandler 類,它所屬于的元件名稱是DotNetNuke 。該類實作了IconfigurationSectionHandler接口傳回ProviderConfiguration 對象,ProviderConfiguration 類中有兩個重要的屬性:DefaultProvider和Providers屬性,即對應着data節中的内容。其中DefaultProvider屬性的類型是字元串,存儲了<data>節defaultProvider屬性值;Providers屬性的類型是哈希表(hashtable),存儲了<providers>下子節<add>的資訊,hashtable的資料結構是名/值對,其名稱對應着<add>節屬性name的值,值則對應着<add>節所有屬性名/值對構成的屬性集合即XmlAttributeCollection資料類型。這個類型的對象是作為Provider類構造函數的參數執行個體化Provider對象的。Provider對象提供了三個屬性:Name,Type,Attributes分别對應着<add>節中的name屬性值,type屬性值,以及其它屬性名/值對構成的集合即NameValueCollection對象。具體的資料庫通路類就是通過Provider類的Attributes屬性獲得資料庫資訊的。
在Reflection類中用第一種方法生成對象時,首先将參數”data”傳遞給函數ConfigurationSettings.GetConfig,這個.NET自帶的靜态函數根據參數”data”在web.config中定位到相應的Section Handle并調用這個Section Handle傳回ProviderConfiguration對象objProviderConfiguration。然後将objProviderConfiguration.Providers(objProviderConfiguration.DefaultProvider)作為構造函數的參數執行個體化一個Provider對象。所要生成的對象的類型名稱即由Provider對象的Type屬性提供。
第二種方法獲得ProviderConfiguration對象的過程和第一種方法相同。然後将第二和第三個參數分别加上字尾字元串ProviderConfiguration對象的DefaultProvider屬性值構成所要生成的對象的類型名稱。這種方法用于執行個體化DNN子產品的具體資料庫通路類。由于DNN子產品可由第三方開發,子產品的名稱空間群組件名稱等可以自定義,不可能針對每一個自定義子產品都在web.config中定義與其相關的配置資訊。是以采用第二種方法,隻要把自定義的名稱空間群組件名稱作為參數傳遞給反射工廠方法即可得到需要執行個體化的類型名稱。而DNN系統的核心功能子產品則采用第一種方法。
Reflection類除了從配置檔案 提取資訊獲得類型名稱并建立相應的執行個體外,還将這個執行個體放入緩存Cache中以提高系統性能。如果不采用反射技術,隻使用一般的工廠方法。當新增一個資料庫類型時就要新增一個具體工廠,進而需要重新編譯主程式,降低了應用程式的可維護性。