The Last Configuration Section Handler You'll Ever Need, take 3

Yet another update the last configuration section handler you will ever need.

Every time I get started with a custom configuration section, I struggle to get the XML correct. This updated class provides two methods that output the correct strings.

        Dim x As New config.XmlSerializerSectionHandler

        Debug.WriteLine(x.CreateConfigSectionDecl(New MyConfig))

        Debug.WriteLine(x.SerializeObjectToConfigXML(New MyConfig))


Nearly all this code is taken or adapted from Jeff Atwood's entry on the topic

Imports System.Configuration

Imports System.Xml.XPath

Imports System.Xml.Serialization

Imports System.Xml

Imports System.Text

 

Namespace Config

 

    Public Class XmlSerializerSectionHandler

        Implements IConfigurationSectionHandler

 

        Public Function Create(ByVal parent As Object, _

        ByVal configContext As Object, _

        ByVal section As System.Xml.XmlNode) As Object _

        Implements IConfigurationSectionHandler.Create

 

            '-- get the name of the type from the type= attribute on the root node

            Dim xpn As XPathNavigator = section.CreateNavigator

            Dim TypeName As String = xpn.Evaluate("string(@type)").ToString

            If TypeName = "" Then

                Throw New ConfigurationException("The type attribute is not present on the root node of " & _

                "the <" & section.Name & "> configuration section ", section)

            End If

 

            '-- make sure this string evaluates to a valid type

            Dim t As Type = Type.GetType(TypeName)

            If t Is Nothing Then

                Throw New ConfigurationException("The type attribute '" & TypeName & _

                "' specified in the root node of the the <" & section.Name & "> configuration section " & _

                "is not a valid type.", section)

            End If

            Dim xs As XmlSerializer = New XmlSerializer(t)

 

            '-- attempt to deserialize an object of this type from the provided XML section

            Dim xnr As New XmlNodeReader(section)

            Try

                Return xs.Deserialize(xnr)

            Catch ex As Exception

                Dim s As String = ex.Message

                Dim innerException As Exception = ex.InnerException

                Do While Not innerException Is Nothing

                    s &= " " & innerException.Message

                    innerException = innerException.InnerException

                Loop

                Throw New ConfigurationException( _

                "Unable to deserialize an object of type '" & TypeName & "' from " & _

                "the <" & section.Name & "> configuration section: " & s, _

                ex, section)

            End Try

        End Function

 

 

        Public Shared Function SerializeObjectToConfigXML(ByVal configObject As Object) As String

            Dim sb As New Text.StringBuilder

            Dim sw As New IO.StringWriter(sb)

            Dim xs As XmlSerializer = New XmlSerializer(configObject.GetType)

            Dim xsn As New XmlSerializerNamespaces

            xsn.Add("", "")

 

            Dim xtw As New Xml.XmlTextWriter(sw)

            xtw.Formatting = Xml.Formatting.Indented

            xtw.WriteRaw("")

 

            xs.Serialize(xtw, configObject, xsn)

            Dim s As String = sb.ToString

            s = System.Text.RegularExpressions.Regex.Replace(s, "(<" + configObject.GetType.Name + ")(>)", _

            "$1 type=""" + configObject.GetType.FullName + ", " + configObject.GetType.Assembly.GetName.Name & """$2")

            Return s

        End Function

 

        Public Function CreateConfigSectionDecl(ByVal ConfigObject As Object) As String

            Dim sb As New StringBuilder

            sb.Append("<section name='")

            sb.Append(ConfigObject.GetType.Name)

            sb.Append("' ")

            sb.Append("type='")

            sb.Append(Me.GetType.FullName)

            sb.Append(", ")

            sb.Append(Me.GetType.Assembly.GetName.Name)

            sb.Append("'/>")

 

            Return sb.ToString

        End Function

 

 

    End Class

End Namespace

Published Monday, January 10, 2005 9:01 PM by swein

Comments

Monday, January 10, 2005 11:39 PM by Jeff Atwood

# re: The Last Configuration Section Handler You'll Ever Need, take 3

Nicely done. It's a great technique originally cribbed from Craig Andera; I just *had* to have that extra error feedback because.. er.. I make mistakes. Frequently.