IConfigurationSectionHandler 這個接口網絡討論的太多了
我剛遇到這個問題,所以也發個實例出來,是我自己的一個框架項目里的一部分。
盡量寫詳細點,歡迎初學者研究。
下面是app.config? web.config也可以的
<configuration>
? <configSections>
??? <section name="Framework" type="CWF.ClassFactory.CWF_ConfigHandler,CWF.ClassFactory"/>
? </configSections>
? <Framework>
??? <ClassFactory>
????? <!-- DataProcess -->
????? <class name="CWF.AbstractSP" type="CWF.DataProcess.CWF_AbstractSP,CWF.DataProcess" />
????? <class name="CWF.SQL" type="CWF.DataProcess.CWF_SQL,CWF.DataProcess" />
????? <class name="CWF.Access" type="CWF.DataProcess.CWF_Access,CWF.DataProcess" />
????? <class name="CWF.Oracle" type="CWF.DataProcess.CWF_Oracle,CWF.DataProcess" />
????? <class name="CWF.ParamList" type="CWF.DataProcess.ParamList,CWF.DataProcess" />
????? <class name="CWF.SimpleProce" type="CWF.DataProcess.CWF_SimpleProce,CWF.DataProcess" />
????? <!--Service-->
????? <class name="CWF.ServiceFactroy" type="CWF.Service.CWF_ServiceFactroy,CWF.Service" />
????? <class name="CWF.AbstractDF" type="CWF.Service.CWF_AbstractDF,CWF.Service" />
????? <class name="CWF.DailyFile" type="CWF.Service.CWF_DailyFile,CWF.Service" />
??? </ClassFactory>
? </Framework>
?
看到在configSections節點下我定義了一個section 節點,這個是段處理器節點,告訴程式他name屬性里指的節點名(本例為“Framework”)采用那個處理程式(type屬性),type屬性就是該段處理程式的具體方法
type="CWF.ClassFactory.CWF_ConfigHandler,CWF.ClassFactory"? 其中CWF.ClassFactory.CWF_ConfigHandler類實現了IConfigurationSectionHandler接口,CWF.ClassFactory是命名空間,以逗號相隔。具體的實現接口的辦法下面將列出代碼。
app.config里的Framework節點是我列出的類工廠里的所有類,設計思路是把底層的實體類和業務應用分開,才用了反射技術,當我們要調用一個類的時候只要告訴程式該類在app.config里的name(這個name也可以自定義),那么他就會讀取class節點name屬性匹配的節點的type屬性,然后反射出該類給調用者使用。
這樣的好處是我們不需要知道具體類的實際名稱和屬性,就可以調用它,并且底層類都寫在app.config里,也不需要你打開api幫助文檔,而且可以返回強類型對象,方便.net的智能提示我們編碼。可能這樣就會問了,反射是很靈活,但反射回來的是object對象,object是弱類型怎么能是強類型呢,其實我在反射上再封裝了一層強類型轉換而已。
下面就看看如何實現這個接口,方便的讀取Framework下面的節點。
在實現這個功能之前首先要了解IConfigurationSectionHandler 是如何工作的。
該接口只有一個方法:
Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) As Object
Create方法,我就是 要實現這個方法。
ConfigurationManager.GetSection("Framework")? 這句話可能我們經常用,其實在我們調用GetSection(舊版本是: ConfigurationSettings.GetConfig)方法的時候他會調用Create方法,應為.NET下的這些類都實現了IConfigurationSectionHandler 接口,比如ConfigurationManager/ConfigurationSettings。
知道了他怎么運行的我們就可以搞定他了
Partial Class CWF_ConfigHandler
??? Implements IConfigurationSectionHandler
??? Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) As Object Implements System.Configuration.IConfigurationSectionHandler.Create
??????? Return New CWFConfiguration(section)
??? End Function
End Class
CWF_ConfigHandler類是我自定義的,他實現IConfigurationSectionHandler接口并完成Ceate方法,這里我還定義了一個類CWFConfiguration并把xmlnode類型的section作為實例參數傳過去,然后我們就在該類里操作xml找到我們要的節點數據。
''' <summary>
''' 獲取類工廠的type類型
''' </summary>
''' <remarks></remarks>
Public Class CWFConfiguration
??? Public FW As XmlNode
??? Public Sub New(ByVal frame As XmlNode)
??????? FW = frame
??? End Sub
??? Public Function getClassType(ByVal className As String) As String
??????? Try
??????????? Return FW.SelectSingleNode("http://ClassFactory//class[@name='" & className & "']").Attributes("type").Value()
??????? Catch ex As Exception
??????????? Return String.Empty
??????? End Try
??? End Function
End Class
這里一個getClassType方法,返回type里的字符串 操作xml就不用多說了吧
我空間有xpath的詳細說明。這樣我們就找到了type里定義的類型。
下面看看如何調用:
Public Class CWF_GetFactory
??? ''' <summary>
??? ''' 獲取類工廠里的類
??? ''' </summary>
??? ''' <param name="className">類名</param>
??? ''' <returns>Object</returns>
??? ''' <remarks></remarks>
??? Public Function getClass(ByVal className As String) As Object
??????? Dim obj As Object = Nothing
??????? Dim cm As CWFConfiguration = CType(ConfigurationManager.GetSection("Framework"), CWFConfiguration)
??????? Dim t As String = cm.getClassType(className)
??????? Dim type As System.Type = System.Type.GetType(t)
??????? obj = Activator.CreateInstance(type)
??????? Return obj
??? End Function
End Class
這個類獲取我們要的用來獲取type里定義的類型,其中一個getClass方法傳遞給他我們查找的name屬性值就可以了
他返回需要的type,然后反射為type類型,實例化對象返回object,這樣我們的工作就完成了。可能你看了這個操作過程會覺得沒有必要這樣做,反而麻煩。但是我們要在系統底層添加一個類,或刪除一個類,就要修改類工廠,甚至更新全部關于該類工廠的所有引用,可能會導致整個工程換面,然而有了這層我們就只需要簡單的改改配置文件就能添加或刪除一個類工廠,對于程式可以不做任何的改動。
這里補充一點:ConfigurationManager 這個必須添加System.Configuration.dll的引用。
好了寫到這里,歡迎留言探討。