Tagged: configurationmanager Toggle Comment Threads | Keyboard Shortcuts

  • aftab 2:43 am on May 29, 2009 Permalink | Reply
    Tags: , , , ConfigurationElementCollection, configurationmanager, ,   

    Writing a complex custom configuration section 

    Technorati Tags: ,

    Here i posted another entry, showing implementation of a simple configuration section, now consider following listing

    <customSection>
        <elements>
          <add name=”FirstAssembly.FirstType” assembly=”FirstAssembly” shouldrun=”true”></add>
        <add name=”SecondAssembly.SecondType” assembly=”SecondAssembly” shouldrun=”true”></add>
        </elements>
      </customSection>

    here we have “n” number of elements in the custom configuration section. To handle this kind of scenario, System.Configuration namespace provides you with ConfigurationPropertyCollection class and ConfigurationPropertyCollectionAttribute class. Your can use ConfigurationPropertyCollection to programmatically write you configuration section and ConfigurationPropertyCollectionAttribute  can be used to do the same job declaratively.

    There are following steps involved in creating a custom configuration section handler with multiple entries.

    1. Define a class (say CustomElement) to represent configuration section by inheriting it from ConfigurationElement class
    2. Define a class to represent your configuration collection (say CustomeElementCollection) by inheriting it from ConfigurationElementCollection, this will hold a collection of the type you defined in step 1.
    3. Define a class to represent your custom section (say CustomSection) by inheriting it from ConfigurationSection and Implement a property of type that you defined in step 2.

    Here is the listing for CustomeElement Class

    public class CustomElement : ConfigurationElement
        {
            public CustomElement()
            {

            }

            [ConfigurationProperty(“name”, IsRequired = true)]
            public string Name
            {
                get { return (string)this[“name”]; }
                set { this[“name”] = value; }
            }

            [ConfigurationProperty(“assembly”, IsRequired = true)]
            public string Assembly
            {
                get { return (string)this[“assembly”]; }
                set { this[“assembly”] = value; }
            }

            [ConfigurationProperty(“shouldrun”, IsRequired = true)]
            public bool ShouldRun
            {
                get { return (bool)this[“shouldrun”]; }
                set { this[“shouldrun”] = value; }
            }
        }

    and here is the listing for CustomElementCollection Class, its implementation is similar to any other Collection class,

    public class CustomeElementCollection : ConfigurationElementCollection
        {
            public CustomeElementCollection()
            {
                CustomElement myElement = (CustomElement)CreateNewElement();
                Add(myElement);
            }
            public void Add(CustomElement customElement)
            {
                BaseAdd(customElement);
            }

            protected override void BaseAdd(ConfigurationElement element)
            {
                base.BaseAdd(element, false);
            }

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

            protected override ConfigurationElement CreateNewElement()
            {
                return new CustomElement();
            }

            protected override object GetElementKey(ConfigurationElement element)
            {
                return ((CustomElement)element).Name;
            }

            public CustomElement this[int Index]
            {
                get
                {
                    return (CustomElement)BaseGet(Index);
                }
                set
                {
                    if (BaseGet(Index) != null)
                    {
                        BaseRemoveAt(Index);
                    }
                    BaseAdd(Index,value);
                }
            }

            new public CustomElement this[string Name]
            {
                get
                {
                    return (CustomElement)BaseGet(Name);
                }
            }

            public int indexof(CustomElement element)
            {
                return BaseIndexOf(element);
            }

            public void Remove(CustomElement url)
            {
                if (BaseIndexOf(url) >= 0)
                    BaseRemove(url.Name);
            }

            public void RemoveAt(int index)
            {
                BaseRemoveAt(index);
            }

            public void Remove(string name)
            {
                BaseRemove(name);
            }

            public void Clear()
            {
                BaseClear();
            }

        }

    and Finally, here is the listing for CustomSection Class,

    class CustomSection:ConfigurationSection
        {
            CustomElement element;
            public CustomSection()
            {
                element = new CustomElement();
            }

            [ConfigurationProperty(“elements”, IsDefaultCollection = false)]
            [ConfigurationCollection(typeof(CustomeElementCollection),AddItemName=”add”,
                ClearItemsName=”clear”,
                RemoveItemName=”remove”)]
            public CustomeElementCollection Elements
            {
                get {
                    return (CustomeElementCollection)base[“elements”]; }
            }
        }

    Next add following settings to your configuration file

    <configSections>
        <section name=”customSection” type=”ConfigurationDemo.CustomSection, ConfigurationDemo” />
      </configSections>

      <customSection>
        <elements>
          <add name=”FirstAssembly.FirstType” assembly=”FirstAssembly” shouldrun=”true”></add>
        <add name=”SecondAssembly.SecondType” assembly=”SecondAssembly” shouldrun=”true”></add>
        </elements>
      </customSection>

    in the end put this custom section to use like this,

    CustomSection myCustomSection = (CustomSection)ConfigurationManager.GetSection(“customSection2”);

                foreach (CustomElement element in mySecondSectionHandler.Elements)
                {
                    if (element.Name != null && element.Name != “”)
                    {
                        string name = element.Name;
                        string assembly = element.Assembly;
                        bool shouldrun = element.ShouldRun;
                    }
                }

     
    • Raza Ali 11:57 am on May 18, 2011 Permalink | Reply

      Thanks! Alhamdulillah! It solved my problem.

    • Michel Abi Raad 12:56 pm on August 29, 2011 Permalink | Reply

      Thanks for this beautiful and easy way of illustration. However, I have one note and one question.

      Note: I guess there is a bug in the “foreach” in the last listing. There is no “mySecondSectionHandler” defined; you should replace this identifier by “myCustomSection”. That is, the second statement in the last listing should be:

      foreach (CustomElement element in myCustomSection.Elements)

      Question: I tried to write to add new elements at runtime to the file, but they do not get saved, even though I used the Configuration.Save method. May you show that please?

      Thanks

  • aftab 10:41 pm on May 28, 2009 Permalink | Reply
    Tags: , , , configurationmanager, ,   

    Writing a Custom Configuration Section 

    Writing your own configuration section involves following steps: –

    1. Define xml structure that will fulfill your configuration needs
    2. Write a class that will represent your custom section by inheriting it from System.Configuration.ConfigurationSection
    3. Add your section, assembly and type representing it, in configSections in your config file.
    4. Add your section anywhere in your config file, within <configuration> root.
    5. Retrieve your custom section using ConfigurationManager.GetSection(“<SectionName”>”)

    Please note that to use ConfigurationSection class you need to add reference to System.Configuration.dll in your project.

    Consider Following xml structure:

    <customSection assembly=”FirstAssembly” type=”FirstAssembly.FirstClass” shouldrun=”true”/>

    Following code snippet defines handler for this configuration structure.

    class CustomSectionHandler:ConfigurationSection
        {
            public CustomSectionHandler()
            {
            }

            [ConfigurationProperty(“assembly”, IsRequired = true)]
            public string Assembly
            {
                get { return (string)this[“assembly”]; }
                set { this[“assembly”] = value; }
            }

            [ConfigurationProperty(“type”,IsRequired=true)]
            public string Type
            {
                get { return (string)this[“type”]; }
                set { this[“type”] = value; }
            }

            [ConfigurationProperty(“shouldrun”,IsRequired=true)]
            public bool ShouldRun
            {
                get {return (bool)this[“shouldrun”];}
                set{this[“shouldrun”]=value;}
            }
        }

    Here you have define a CustomSectionHandler class that is inheriting from Configuration.ConfigurationSection class then you have define three properties (representing three attributes of the custom section) and you have decorated all these properties with ConfigurationProperty Attribute.

    Next add your section in your .config file in the configSections

    <configSections>
        <section name=”customSection” type=”ConfigurationDemo.CustomSectionHandler, ConfigurationDemo”/>
      </configSections>

    where name is; just name of your section using which you can refer to it in your code and your configuration files while type is “<fully qualified name of handler type>,<Assembly that contains it>”.

    SO that was it, your custom section handler is ready, now you can put it to your service like this,

    CustomSectionHandler mySectionHandler = (CustomSectionHandler) ConfigurationManager.GetSection(“customSection”); 

    string assembly = mySectionHandler.Assembly; 
    string type = mySectionHandler.Type; 
    bool shouldRun = mySectionHandler.ShouldRun;

     

    Happy Programming!

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel