Thoughts on life, liberty, and information technology

Simplify configuration with a generic ConfigurationElementCollection class

I’ve been using Phil Haack‘s Custom Configuration Sections in 3 Easy Steps for some time now, and my configuration file management has never been happier… until I needed to read a collection of configuration elements.

Here’s a sample of the XML I needed to incorporate:


	
		
		
	   

The typical solution is to write your own collection class (FilespecConfigurationElementCollection), inheriting from ConfigurationElementCollection, and ensuring your Filespec object inherits from ConfigurationElement. I figured there has to be a better way — and there is.

I wrote a generic version of ConfigurationElementCollection, which you can use to avoid writing the custom collection class. The code that follows is the generic class, the Filespec object I used, and the property declaration from my ConfigurationSettings class (as described in Phil’s previously mentioned article).

Note one key part of this implementation: You must override the ToString() method of your custom ConfigurationElement class to return a unique value. The generic ConfigurationElementCollection uses the ToString() method to obtain a unique key for each element in the collection.

// The ConfigurationElementCollection provides a simple generic implementation of ConfigurationElementCollection.
[ConfigurationCollection(typeof(ConfigurationElement))]
public class ConfigurationElementCollection : ConfigurationElementCollection where T : ConfigurationElement, new()
{
	protected override ConfigurationElement CreateNewElement()
	{
		return new T();
	}
	protected override object GetElementKey(ConfigurationElement element)
	{
		return ((T)(element)).ToString();
	}
	public T this[int idx]
	{
		get { return (T)BaseGet(idx); }
	}
}
// The Filespec class is an example of a custom configuration element.
// Note that we inherit from ConfigurationElement, and use ConfigurationProperty attributes.
public class Filespec : ConfigurationElement
{
	public Filespec()
	{
	}
	[ConfigurationProperty("path", DefaultValue="", IsKey=true, IsRequired=true)]
	public string Path
	{
		get { return (string)(base["path"]); }
		set { base["path"] = value; }
	}
	[ConfigurationProperty("type", IsKey=false, IsRequired = true)]
	public FilespecType Type
	{
		get { return (FilespecType)(base["type"]); }
		set { base["type"] = value; }
	}

	public override string ToString()
	{
		return this.Path;
	}
}
// Finally, our ConfigurationSettings class (only part of the class is included).
// Note how we use the generic ConfigurationElementCollection.
public class ConfigurationSettings : ConfigurationSection
{
// ...
	[ConfigurationProperty("filespecs", IsRequired=true)]
	public ConfigurationElementCollection FileSpecs
	{
		get { return (ConfigurationElementCollection)this["filespecs"]; }
	}
// ...
}

If you’re using a number of ConfigurationElementCollections, this is a great way to simplify your code.

2 responses to “Simplify configuration with a generic ConfigurationElementCollection class”

  1. Ron Avatar
    Ron

    Great, but how to use this on an existing config file ?

    Like

  2. Ron Avatar
    Ron

    Ok, I got it to work. Great.

    Like

Leave a reply to Ron Cancel reply