Paul's Petrov Whiteboard

[BizTalk, Enterprise Application Integration, Business Process Automation, SOA, .NET]

  Home  |   Contact  |   Syndication    |   Login
  51 Posts | 1 Stories | 55 Comments | 30 Trackbacks

News

Archives

Post Categories

Image Galleries

BizTalk

Other

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");

 

posted on Tuesday, November 13, 2007 1:32 PM

Feedback

# re: Generic custom configuration elements collection based on ConfigurationElementCollection 12/12/2007 1:29 PM tim mackey
thanks for posting this, took me a while to figure out but i got it in the end! very useful. just for anyone else who gets stuck on the app.config syntaxt like i did (i found the MSDN docs on Custom Config Collections very confusing), this may help:

<configuration>
<configSections>
<section name="mySection" type="MyNameSpace.MyCustomConfigSection, MyAssembly" allowLocation="true" allowDefinition="Everywhere" />

...

<mySection>
<MyCustomSettings>
<add ElementKey="1" Name="Whatever1" />
<add ElementKey="2" Name="Whatever2" />
<add ElementKey="3" Name="Whatever3" />
</MyCustomSettings>
</mySection>

# re: Generic custom configuration elements collection based on ConfigurationElementCollection 1/27/2008 5:13 PM Lenny Miller
What does the CustomConfigElementBase class look like?



# re: Generic custom configuration elements collection based on ConfigurationElementCollection 1/28/2008 10:13 PM Paul Petrov
Lenny,

CustomConfigElementBase is your own implementation of System.Configuration.ConfigurationElement class. It defines whatever properties you want to be inherited by all custom configuration elements. In my example, it's an ElementKey property. If your elements don't have shared properties, you can use ConfigurationElement but in generic collection GetElementKey() method implementation you'd use reflection to return current type's key.

The whole idea described makes sense if you have many custom configuration elements. It saves some repetitive coding, i.e. defining strongly typed collection of each custom element type created. In case of one or two custom elements we don't gain much, just use regular approach with typed collections.

# re: Generic custom configuration elements collection based on ConfigurationElementCollection 4/8/2008 8:05 AM Xor2
How to this value, not the attribute?

<MyCustomSettings>
<add>Value</add>
</MyCustomSettings>

Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 2 and 8 and type the answer here: