Writing a Complex Custom Configuration Section






4.31/5 (7 votes)
How to write a complex custom configuration section
Here I posted another entry, showing the implementation of a simple configuration section. Now consider the following listing:
<customSection>
<elements>
<add name="FirstAssembly.FirstType" assembly="FirstAssembly" shouldrun="true" />
<add name="SecondAssembly.SecondType" assembly="SecondAssembly" shouldrun="true" />
</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 the ConfigurationPropertyCollection
class and ConfigurationPropertyCollectionAttribute
class. Your can use ConfigurationPropertyCollection
to programmatically write your configuration section and ConfigurationPropertyCollectionAttribute
can be used to do the same job declaratively.
Listed below are the steps involved in creating a custom configuration section handler with multiple entries.
- Define a class (say
CustomElement
) to represent configuration section by inheriting it fromConfigurationElement
class - Define a class to represent your configuration collection (say
CustomElementCollection
) by inheriting it fromConfigurationElementCollection
. This will hold a collection of the type you defined in step 1 - Define a class to represent your custom section (say
CustomSection
) by inheriting it fromConfigurationSection
and implement a property of the type that you defined in step 2
Here is the listing for CustomElement
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 the 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 name="SecondAssembly.SecondType"
assembly="SecondAssembly" shouldrun="true" />
</elements>
</customSection>
In the end, put this custom section to use like this:
CustomSection myCustomSection = (CustomSection)ConfigurationManager.GetSection("customSection");
foreach (CustomElement element in myCustomSection.Elements)
{
if (element.Name != null && element.Name != "")
{
string name = element.Name;
string assembly = element.Assembly;
bool shouldrun = element.ShouldRun;
}
}