Managing Configuration Manager Part 3 – Section and SectionGroup

So far, all of our classes are either a ConfigurationElement or a Collection of it. We can’t use Elements in a configuration as is. They need to be contained in a Section.

Enter ProcessGroup. This is our first Section. It contains an array of Groups in a neat GroupCollection and no string properties at all.

    public class ProcessGroup : ConfigurationSection
        private static ConfigurationProperty oGroupCollection;

        private static ConfigurationPropertyCollection oProperties;

        private static ProcessGroup thisSection;

        public ProcessGroup()
            oGroupCollection = new ConfigurationProperty(
            oProperties = new ConfigurationPropertyCollection();


        [ConfigurationProperty("groups", IsRequired = true)]
        [ConfigurationCollection(typeof(Group), AddItemName = "group")]
        public GroupCollection Groups
            get { return (GroupCollection)base[oGroupCollection]; }

        public static ProcessGroup GetSection()
            return GetSection("processGroups");

        public static ProcessGroup GetSection(string definedName)
            if (thisSection == null)
                thisSection = ConfigurationManager.GetSection(definedName) as ProcessGroup;
                if (thisSection == null)
                    throw new ConfigurationErrorsException("The <" + definedName + "> section is not defined in your .config file!");

            return thisSection;

        protected override ConfigurationPropertyCollection Properties
            get { return oProperties; }

The only difference here from Group, aside from this extending from ConfigurationSection, is the GetSection methods. These methods make it easy to get the Section from app.config. It also applies a simple Singleton pattern by keeping a reference of the Section in memory when it finds it. For huge Sections, this could be a performance bonus.

Now, my original ‘requirements’ only calls for a single Section, but I’d rather have the foundation ready before I need it. So let’s add a SectionGroup.

    public class ProcessSettings : ConfigurationSectionGroup
        public ProcessSettings() { }

        public ProcessGroup ProcessGroups()
            return ProcessGroup.GetSection();

Tada! That’s it. The entire SectionGroup only has one method to call the only Section in this SectionGroup. When I later add new Section, all I need to add is a method to get them in this class.

For the app.config itself, we need to add entries to the <configSections> so the XML is strongly typed.

    <sectionGroup name="processSettings"
                  type="ModuleProcessor.Configuration.ProcessSettings, ModuleProcessor">
      <section name="processGroups"
               type="ModuleProcessor.Configuration.LinkGroup, ModuleProcessor"/>

Furthermore, the actual configuration now becomes:

        <group name="Group 1">
          <modules order="1" name="SomeModules" path="Project1" />
          <modules order="2" name="OtherModule" path="Project2" />
        <group name="Group 2">
          <modules order="3" name="YetAnotherModule" path="OtherProject" />

Now, to use this in actual code, you’ll need help from ConfigurationManager

  Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  ProcessSettings Settings = (ProcessSettings)Config.GetSectionGroup("processSettings");
  ProcessGroup GroupSection = Settings.Sections["processGroups"];
  Group[] Groups = GroupSection.Groups;
  Module[] Modules = Groups[0].Modules;
  string NameOfModuleOneGroupOne = Modules[0].Name;                        // "SomeModule"
  string NameOfModuleTwoGroupOne = GroupSection.Groups[0].Modules[1].Name; // "OtherModule"
  string PathOfModuleOneGroupTwo = GroupSection.Groups[1].Modules[0].Path; // "OtherProject"

Leave a Reply