Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Nested Element in Application Config File

0.00/5 (No votes)
5 Oct 2010 1  
Learn how to build nested element in app.config file with .NET configuration library

Introduction

The use of configuration file is a crucial aspect to modify applications behaviour without changing the internal code. In .NET, there are powerful features to manage the settings file in XML format. The use of application setting composed of a couple name value attributes is immediate! When you try to implement your custom configuration file for your business logic starts the trouble. In this article, I present a solution to structure nested element in a separate configuration file.

External File

In order to have a separate configuration file to make distinct configuration for different parts of the application, I add the following code into the app.config:

<sectionGroup name="customSectionGroup" type="ecoLDS_HMI.CustomConfigSectionGroup, 
	ecoLDS_HMI">
   <section name="customUserSettings" type="ecoLDS_HMI.CustomConfigSection, ecoLDS_HMI"/>
</sectionGroup>   
 <customSectionGroup >
    <customUserSettings configSource="UserSettings.config" />
  </customSectionGroup>  

Specifying the configuration source, the custom user settings are stored in a separate file called UserSettings.config.

Custom .config File

In the UserSetting.config file, I stored my custom configuration composed of zooms node as root element and a sequence of zoomLine node with inside sequence of zoomZone. I use this type of configuration file to set up my map component for a different level of zoom depending on the structure of the line.

<customUserSettings userName="Enrico" expiresOn="10/10/2017" >
  <zooms>
    <zoomLine numLinea="1">
      <zones>
        <zoomZone numNode="1" zoomValue="200"/>
        <zoomZone numNode="5" zoomValue="300"/>
      </zones>
    </zoomLine>
    <zoomLine numLine="2" >
      <zones>
        <zoomZone numNode="1" zoomValue="200"/>
        <zoomZone numNode="2" zoomValue="200"/>
      </zones>
    </zoomLine>
  </zooms>
</customUserSettings>

Implementation

In order to read my config file UserSetting.config I exploited the System.Configuration library of .NET Framework extending the class ConfigurationSection, ConfigurationElementCollection and ConfigurationElement.

To read the section represented by the node customUserSettings with the two attributes userName and expiresOn, I extended the class ConfigurationSection adding a configuration property for each attribute and for the sub element zooms.

 Public Class CustomConfigSection
    Inherits ConfigurationSection
    Public Sub New()
    End Sub
    <ConfigurationProperty("userName")> _
     Public Property UserName() As String
        Get
            Return CType(Me("userName"), String)
        End Get
        Set(ByVal value As String)
            Me("userName") = value
        End Set
    End Property

    <ConfigurationProperty("expiresOn")> _
    Public Property ExpiresOn() As String
        Get
            Return CType(Me("expiresOn"), String)
        End Get
        Set(ByVal value As String)
            Me("expiresOn") = value
        End Set
    End Property

    <ConfigurationProperty("zooms")> _
    Public ReadOnly Property CustomConfigElementCollection() As ZoomLineCollection
        Get
            Return TryCast(Me("zooms"), ZoomLineCollection)
        End Get
    End Property

End Class

The last configuration property zooms contain a list of ZoomLine elements collected in a collection called ZoomLineCollection.

The class implemented to read the ZoomLine element extends ConfiguarationElement class. We have added a configuration property for each attribute and a configuration property for the element zones following the previous pattern.

The zones configuration property contain a collection of zone element.

Public Class ZoomLine
    Inherits ConfigurationElement

    <ConfigurationProperty("numLine", DefaultValue:="0", IsKey:=True)> _
    <IntegerValidator(MinValue:=0, MaxValue:=200)> _
    Public Property NumLinea() As Integer
        Get
            Return CType(Me("numLine"), Integer)
        End Get
        Set(ByVal value As Integer)
            Me("numLine") = value
        End Set
    End Property
    <ConfigurationProperty("zones")> _
    Public ReadOnly Property CustomConfigElementCollection() As ZoomZonesCollection
        Get
            Return TryCast(Me("zones"), ZoomZonesCollection)
        End Get
    End Property
End Class 

The class ZoomLineCollection extends ConfigurationElementCollection class and reads the sequence of zoomLine elements. The declarative configuration AddItemName:="zoomLine" connects the XML node with the corresponding class that composed the collection in this case zoomLine.

<ConfigurationCollection(GetType(ZoomLinea), AddItemName:="zoomLine")> _
Public Class ZoomLineCollection
    Inherits ConfigurationElementCollection

    Protected Overrides Function CreateNewElement() As ConfigurationElement
        Return New ZoomLinea()
    End Function

    Public Sub Add(ByVal valueInteger As Integer)
        Dim newElement As ZoomLinea = TryCast(Me.CreateNewElement(), ZoomLine)
        newElement.NumLine = valueInteger
        MyBase.BaseAdd(newElement)
    End Sub

    Protected Overrides Function GetElementKey_
	(ByVal element As System.Configuration.ConfigurationElement) As Object
        Dim elem As ZoomLine = TryCast(element, ZoomLine)
        Return elem.NumLinea
    End Function

End Class

The remaining two classes to read and collect the zoomZone elements follow the structure of the previous one.

Public Class ZoomZone
    Inherits ConfigurationElement
    <ConfigurationProperty("numNode", DefaultValue:="-1", _
		IsKey:=False, IsRequired:=False)> _
    Public Property NumNode() As Integer
        Get
            Return CType(Me("numNode"), Integer)
        End Get
        Set(ByVal value As Integer)
            Me("numNode") = value
        End Set
    End Property
    <ConfigurationProperty("zoomValue", DefaultValue:="100", _
		IsKey:=False, IsRequired:=False)> _
    <IntegerValidator(MinValue:=100, MaxValue:=500)> _
    Public Property ZoomValue() As Integer
        Get
            Return CType(Me("zoomValue"), Integer)
        End Get
        Set(ByVal value As Integer)
            Me("zoomValue") = value
        End Set
    End Property
End Class
<ConfigurationCollection(GetType(ZoomZone), AddItemName:="zoomZone")> _
Public Class ZoomZonaCollection
    Inherits ConfigurationElementCollection

    Protected Overrides Function CreateNewElement() As ConfigurationElement
        Return New ZoomZone()
    End Function

    Public Sub Add(ByVal valueString As String, ByVal valueInteger As Integer)
        Dim newElement As ZoomZona = TryCast(Me.CreateNewElement(), ZoomZone)
        newElement.NumNode = valueString
        newElement.ZoomValue = valueInteger
        MyBase.BaseAdd(newElement)
    End Sub

    Protected Overrides Function GetElementKey_
	(ByVal element As System.Configuration.ConfigurationElement) As Object
        Dim elem As ZoomZona = TryCast(element, ZoomZone)
        Return elem.NumNode
    End Function
End Class

Conclusion

The .NET configuration library provides useful features that need to be discovered, as the declarative specification of the configuration properties.

To implement the nested element, I followed these two rules:

  • For each sequence of elements, I implemented a collection.
  • For each node, I implemented a configuration element class with a configuration property
    • for each attribute
    • for each child node

History

  • 5th October, 2010: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here