Click here to Skip to main content
11,503,750 members (73,383 online)
Click here to Skip to main content

Tagged as

How to Implement Custom configSection with Nested Elements in C#

, 8 May 2014 CPOL 10.4K 7
Rate this:
Please Sign up or sign in to vote.
After completing this exercise, you should be able to implement custom configSection, with nested elements, in your application's config file.

Objective: After completing this exercise, you should be able to implement custom configSection, with nested elements, in your application’s config file.

In my previous post, How to implement custom configSection in your configuration, I have explained the details about how to implement simple single element based custom configSection in your configuration, i.e., without any nested elements.

However in many scenarios, we need to implement custom configSection having nested elements. It is very useful in cases where you need to store some limited number of configuration details or any data, and you do not want to use database for storing those configurations.

Here, I will explain the step by step process to implement custom configSection with nested elements. Like most of my posts, I have followed a practical approach rather than providing theory. Following this, you will be able to achieve the goal of the post.

Step 1: Create a new Console application named as “CustomNestedConfigSection”.

Step 2: Create a folder under this project named as “NestedConfig”.

Step 3: Add a new App.config file to the project.

Step 4: Add a new class file “EmployeesConfigSection.cs” in NestedConfig folder as below:

using System.Configuration;

namespace CustomNestedConfigSections.NestedConfig
{
    public class EmployeesConfigSection : ConfigurationSection
    {
        //If you replace "employeeCollection" with "" then you do not need "employeeCollection" element as a wrapper node over employee nodes in config file.
        [ConfigurationProperty("employeeCollection", IsDefaultCollection = true, IsKey = false, IsRequired = true)]
        public EmployeeCollection Members
        {
            get
            {
                return base["employeeCollection"] as EmployeeCollection;
            }

            set
            {
                base["employeeCollection"] = value;
            }
        }

    }
}

Step 5: Add a new class file “EmployeeCollection.cs” in NestedConfig folder as below:

using System;
using System.Configuration;

namespace CustomNestedConfigSections.NestedConfig
{
    public class EmployeeCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new Employee();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((Employee) element).Id;
        }

        protected override string ElementName
        {
            get
            {
                return "employee";
            }
        }

        protected override bool IsElementName(string elementName)
        {
            return !String.IsNullOrEmpty(elementName) && elementName == "employee";
        }

        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.BasicMap;
            }
        }

        public Employee this[int index]
        {
            get
            {
                return base.BaseGet(index) as Employee;
            }
        }

        public new Employee this[string key]
        {
            get
            {
                return base.BaseGet(key) as Employee;
            }
        }
    }
}

Step 6: Add a new class file “Employee.cs” in NestedConfig folder as below:

using System.Configuration;

namespace CustomNestedConfigSections.NestedConfig
{
    public class Employee : ConfigurationElement
    {
        [ConfigurationProperty("id", IsKey = true)]
        public string Id { get { return (string) this["id"]; } }

        [ConfigurationProperty("personalInfo")]
        public PersonalInfo PersonalInfo
        {
            get { return (PersonalInfo)this["personalInfo"]; }
        }

        [ConfigurationProperty("homeAddress")]
        public Address HomeAddress { get { return (Address)this["homeAddress"]; } }

        [ConfigurationProperty("officeAddress")]
        public Address OfficeAddress { get { return (Address)this["officeAddress"]; } }
    }
}

Step 7: Add a new class file “PersonalInfo.cs” in NestedConfig folder as below:

using System.Configuration;

namespace CustomNestedConfigSections.NestedConfig
{
    public class PersonalInfo : ConfigurationElement
    {
        [ConfigurationProperty("ssn", IsKey = true)]
        public string SSN { get { return (string)this["ssn"]; } set { this["ssn"] = value; } }

        [ConfigurationProperty("height")]
        public int Height { get { return (int)this["height"]; } set { this["height"] = value; } }

        [ConfigurationProperty("weight")]
        public int Weight { get { return (int)this["weight"]; } set { this["weight"] = value; } }
    }
}

Step 8: Add a new class file “Address.cs” in NestedConfig folder as below:

using System.Configuration;

namespace CustomNestedConfigSections.NestedConfig
{
    public class Address : ConfigurationElement 
    {
        [ConfigurationProperty("pin")]
        public string PinCode { get { return (string) this["pin"]; } }

        [ConfigurationProperty("city")]
        public string City { get { return (string)this["city"]; } }

        [ConfigurationProperty("state")]
        public string State { get { return (string)this["state"]; } }
    }
}

Step 9: Modify “App.config” file in your application as below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="employeeCollectionSection" 
    type="CustomNestedConfigSections.NestedConfig.EmployeesConfigSection, 
    CustomNestedConfigSections"/>
  </configSections> 
  <employeeCollectionSection>
    <employeeCollection>
      <employee id="1">
        <personalInfo ssn="3243423" height="342"  weight="78" />
        <homeAddress pin="411001" city="Pune" state="Maharashtra"/>
        <officeAddress pin="844101" city="Shahdra" state="Delhi"/>
      </employee>
      <employee id="2">
        <personalInfo ssn="7435623" height="342" weight="62" />
        <homeAddress pin="411002" city="Pimpri" state="Maharashtra"/>
        <officeAddress pin="874785" city="Mangolpuri" state="Haryana"/>
      </employee>
    </employeeCollection>
  </employeeCollectionSection>
</configuration>

Step 10: Modify “Program.cs” file in your application as below:

using System;
using System.Configuration;
using CustomNestedConfigSections.NestedConfig;

namespace CustomNestedConfigSections
{
    class Program
    {
        static void Main(string[] args)
        {
            var employee1 = GetEmployee("1");
            Console.WriteLine("\n\nDetails of employee with id : 1");
            Console.WriteLine("Personal Info: SSN - {0} Height - {1}inch Weight - {2}Kg", 
            employee1.PersonalInfo.SSN, employee1.PersonalInfo.Height,employee1.PersonalInfo.Weight);
            Console.WriteLine("Home Address : {0} {1} {2}", employee1.HomeAddress.City, 
            employee1.HomeAddress.State, employee1.HomeAddress.PinCode);
            Console.WriteLine("Office Address : {0} {1} {2}", employee1.OfficeAddress.City, 
            employee1.OfficeAddress.State, employee1.OfficeAddress.PinCode);

            Console.ReadKey();
        }

        public static Employee GetEmployee(string employeeId)
        {
            var employeesConfigSection = ConfigurationManager.GetSection
            ("employeeCollectionSection") as EmployeesConfigSection;

            if (employeesConfigSection == null || 
            employeesConfigSection.Members == null || employeesConfigSection.Members.Count < 1)
                return null;

            return employeesConfigSection.Members[employeeId];
        }
    }
}

Step 11: Run your console application. Do not forget to add reference of “System.Configuration” in your console application project. I hope you will not get any error while running the application. However if you get one, you would be able to fix it.

Now I will explain the terms or points which have not been covered above.

  • For each element/node in your config, you need to create a corresponding class which derives from “ConfigurationElement”.
  • To define an attribute for any element/node, you need to create a public property with “ConfigurationProperty” attribute. For example, if you want to create an attribute named “city” for an element, then define a property like:
[ConfigurationProperty("city")]
public string City { get { return (string)this["city"]; } }
  • You define the name of element/node/attribute inside “ConfigurationProperty” attribute.
  • If you want more than one child node under an element or node, then you need to create a new class for that collection which should be derived from “ConfigurationElementCollection”. Here, you also define name of the element which represents your collection as I have created “employee" for employee collection.
  • To create root element/node for your configSection, you must create a class which derives from “ConfigurationSection”. To create simplest configSection, you need a single class derived from “ConfigurationSection” having properties, with ConfigurationProperty attribute, corresponding to required attributes.
  • If you do not want wrapper element/node for your collection, then replace ConfigurationProperty name with blank. For example, if you do not want “employeeCollection” element/node in your config file, then replace ConfigurationProperty name with blank from EmployeesConfigSection as below:
        //If you replace "employeeCollection" with "" then you do not need "employeeCollection" element as a wrapper node over employee nodes in config file.
        [ConfigurationProperty("", IsDefaultCollection = true, IsKey = false, IsRequired = true)]
        public EmployeeCollection Members
        {
            get
            {
                return base[""] as EmployeeCollection;
            }

            set
            {
                base[""] = value;
            }
        }

After making the above changes, configSection in your App.config file should be modified as:

  <employeeCollectionSection>
    <employee id="1">
      <personalInfo ssn="3243423" height="342"  weight="78" />
      <homeAddress pin="411001" city="Pune" state="Maharashtra"/>
      <officeAddress pin="844101" city="Shahdra" state="Delhi"/>
    </employee>
    <employee id="2">
      <personalInfo ssn="7435623" height="342" weight="62" />
      <homeAddress pin="411002" city="Pimpri" state="Maharashtra"/>
      <officeAddress pin="874785" city="Mangolpuri" state="Haryana"/>
    </employee>
  </employeeCollectionSection>
  • You will have n level of nesting of elements in this way. You will have n classes for n elements you need in your configuration.
  • You can define a static class for easy manipulation of configuration values. I have defined static methods in Program class for the purpose to get employee with given id.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Adarsh Chaurasia (Learner|Consultant|Mentor|Tech
Software Developer (Senior)
India India
I have 5.5+ years of experience in SaaS, SOA based Enterprise Web Application design and development using Microsoft technology stack. I have mostly worked on Business layer, Data access layer, WCF, Entity Framework, Microsoft Application Blocks, Search engines, APIs integration, Third party APIs/Product Research & Development.

I am a huge fan of Design Patterns. I also work as Software Consultant. I read/write blogs, help and learn from other developers.
Follow on   Twitter   LinkedIn

Comments and Discussions

 
QuestionNested Configuration Pin
Rajaraman Soundar29-Sep-14 12:42
memberRajaraman Soundar29-Sep-14 12:42 
AnswerRe: Nested Configuration Pin
Adarsh Chaurasia (Consultant|Mentor|Tech Savvy)29-Sep-14 21:44
memberAdarsh Chaurasia (Consultant|Mentor|Tech Savvy)29-Sep-14 21:44 
QuestionNested Configuration Pin
Rajaraman Soundar29-Sep-14 12:35
memberRajaraman Soundar29-Sep-14 12:35 
GeneralMy vote of 5 Pin
abeethadesilva1-Aug-14 1:53
memberabeethadesilva1-Aug-14 1:53 
QuestionMembershipElement ? Pin
Member 30687318-May-14 2:04
memberMember 30687318-May-14 2:04 
AnswerRe: MembershipElement ? Pin
Adarsh Kumar Chaurasia8-May-14 3:28
memberAdarsh Kumar Chaurasia8-May-14 3:28 
GeneralRe: MembershipElement ? Pin
Member 30687318-May-14 22:23
memberMember 30687318-May-14 22:23 
GeneralRe: MembershipElement ? Pin
Adarsh Kumar Chaurasia9-May-14 4:42
memberAdarsh Kumar Chaurasia9-May-14 4:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 8 May 2014
Article Copyright 2014 by Adarsh Chaurasia (Learner|Consultant|Mentor|Tech
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid