Simple trick that saves me some time and coding when writing custom configuration objects is to define generic collection for them. Let's say I created several custom configuration elements derived from my CustomConfigElementBase which in turn inherits from System.Configuration.ConfigurationElement. Instead of defining strongly typed collections for each type I can simply define class:
public class GenericConfigElementCollection<T> : ConfigurationElementCollection
where T : CustomConfigElementBase, new()
{
public T this[int index]
{
get
{
return base.BaseGet(index) as T;
}
set
{
if (base.BaseGet(index) != null)
base.BaseRemoveAt(index);
base.BaseAdd(index, value);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new T();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((T)element).ElementKey;
}
}
Note, that base custom configuration element has property ElementKey to satisfy GetElementKey method implementation. If your custom elements have different keys, you can override this property. It's possible to skip CustomConfigElementBase and define generic collection with ConfigurationElement type restriction. GetElementKey implementation would use reflection to retreive key property:
public class GenericConfigElementCollection<T> : ConfigurationElementCollection
where T : ConfigurationElement, new()
{
protected override object GetElementKey(ConfigurationElement element)
{
//- find and return property which is a key for a given type T using reflection
...
}
}
Now, when we define configuration section we just return generic collection of appropriate type:
public class MyCustomConfigSection : ConfigurationSection
{
[ConfigurationProperty("myCustomSettings", IsRequired = true)]
public GenericConfigElementCollection<MyCustomConfigElement> MyCustomSettings
{
get
{
return this["myCustomSettings"]
as GenericConfigElementCollection<MyCustomConfigElement>;
}
}
}
And then just use it in an application code:
GenericConfigElementCollection<MyCustomConfigElement> configCollection = configSection.MyCustomSettings;
MyCustomConfigSection configSection = (MyCustomConfigSection)ConfigurationManager.GetSection("mySection");