Incomplete Leo

Something from my heart

Custom configuration for NET 2.0

http://blogs.neudesic.com/blogs/jason_jung/archive/2006/08/08/208.aspx

Custom Configuration Section Handler in .NET 2.0

I recently had to deal with creating custom sections in the web/app.config file. In the .NET 1.x realm, I had to create a section handler which implements public class CustomSectionHandler: IConfigurationSectionHandler.

In 2.0, we have to create a custom section handler that derives from ConfigurationSection, which then can be used to contain public properties that map the attributes in the configuration file.

For example, Let’s say that we have the following custom section in web.config:

MySection Attribute1=”1″ Attribute2=”x” />

We can write a custom section like the following:

using System.Configuration;

public class MyConfigSection: ConfigurationSection

{

[ConfigurationProperty("Attribute1", IsKey = true, IsRequired = true)]

public int Attribute1

{

get { return (int)this["Attribute1"]; }

set { this["Attribute1"] = value; }

}

[ConfigurationProperty("Attribute2")]

public string Attribute2

{

get { return (string)this["Attribute2"]; }

set { this["Attribute2"] = value; }

}

}

If you want to support mutiple elements within a config section, you can do so by creating another class that derives from ConfigurationElementCollection to maintain a collection of the configuration element. We can tweak the custom section in the web.config file a little bit to support this.

MyConfigSection>

Employees>

Employee EmployeeID=alincoln FirstName=abraham LastName=lincoln />

Employee EmployeeID=gwashington FirstName=george LastName=washington />

Employee EmployeeID=gbush FirstName=george LastName=bush />

Employees>

MyConfigSection>

Then, we can write the custon section like this:

public class MyConfigSection: ConfigurationSection

{

[ConfigurationProperty("Employees", IsDefaultCollection = true)]

public EmployeeCollection Employees

{

get { return (EmployeeCollection) base["Employees"]; }

}

}

public sealed class EmployeeElement : ConfigurationElement

{

[ConfigurationProperty("EmployeeID", IsKey = true, IsRequired = true)]

public string EmployeeID

{

get { return (string)this["EmployeeID"]; }

set { this["EmployeeID"] = value; }

}

[ConfigurationProperty("FirstName", IsRequired = true)]

public string FirstName

{

get { return (string)this["FirstName"]; }

set { this["FirstName"] = value; }

}

[ConfigurationProperty("LastName", IsRequired = true)]

public string LastName

{

get { return (string)this["LastName"]; }

set { this["LastName"] = value; }

}

}

public sealed class EmployeeCollection : ConfigurationElementCollection

{

protected override ConfigurationElement CreateNewElement()

{

return new EmployeeElement();

}

protected override object GetElementKey(ConfigurationElement element)

{

return ((EmployeeElement)element).EmployeeID;

}

public override ConfigurationElementCollectionType CollectionType

{

get { return ConfigurationElementCollectionType.BasicMap; }

}

protected override string ElementName

{

get { return “Employee”; }

}

public EmployeeElement this[int index]

{

get { return (EmployeeElement)BaseGet(index); }

set

{

if (BaseGet(index) != null)

{

BaseRemoveAt(index);

}

BaseAdd(index, value);

}

}

new public EmployeeElement this[string employeeID]

{

get{return (EmployeeElement)BaseGet(employeeID);}

}

public bool ContainsKey(string key)

{

bool result = false;

object[] keys = BaseGetAllKeys();

foreach (object obj in keys)

{

if ((string)obj == key)

{

result = true;

break;

}

}

return result;

}

}

I’ve added the ContainsKey() Method to the EmployeeCollection class because I couldn’t find a simpler way to check for the existence of a given key. Maybe there is a better solution..

Now you need to add the custom section to the ConfigSections in the coniguration file.

section name=MyConfigSection type=Namespace.ClassName, AssemblyName />

Lastly, you can access the config section from your code the following way:

MyConfigSection employeeSection=

(MyConfigSection )System.Configuration.ConfigurationManager.GetSection(“MyConfigSection”);

I hope it helps!

############# NESTED ELEMENT ###############

It is fairly easy to create nested elements. You would create another pair of classes which inherit from ConfigurationElement and ConfigurationElementCollection, and add a property that represents the new ConfigurationElementCollection to a parent element.

In my example, I have a group of Employees. If I wanted to extend it to have another nested set of nodes within an EmployeeElement, I can create EmployeeChildNodes and EmployeeChildNode that inherit from ConfigurationElementCollection and ConfigurationElement respectively. Then, I can add a property to my EmployeeElement class like this:

[ConfigurationProperty("EmployeeChildNodes", IsDefaultCollection = true)]

public EmployeeChildNodeCollection EmployeeChildNodes

{

get { return (EmployeeChildNodeCollection ) base["EmployeeChildNodes"]; }

}

This will ccver a config section like this:

<MyConfigSection>
<Employees>
<Employee>
<EmployeeChildNodes>
<EmployeeChildNode>

</EmployeeChildNode>
<EmployeeChildNode>

</EmployeeChildNode>
</EmployeeChildNodes>
</Eemployee>

<Employee>
<EmployeeChildNodes>
<EmployeeChildNode>

</EmployeeChildNode>
<EmployeeChildNode>

</EmployeeChildNode>
</EmployeeChildNodes>
</Eemployee>
<Employees>
<MyConfigSection>


####################

By the way, in the ConfigurationElementCollection child (EmployeeCollection), you need to overwrite the IsElementName property for this to sample to work.

IsElementName should look like something like this:

protected override bool IsElementName(string elementName)
{
return elementName == “Employee”;
}

This way the Employee tags inside of Employees tag will get picked up by configuration runtime and properly initialized.

Also if you want to programmatically add elements to the EmployeeCollection, you need to override SerializeElement of ConfigurationElement.

Take care,
Sasha

8 phản hồi »

  1. Thank for your sharing ! It’s so cool!

    Phản hồi bởi Nong Tien Bac | Tháng Ba 14, 2008 | Trả lời

  2. Sasha,

    Thanks for the post on this workaround! It’s awesome code and was just what I needed to help me figure out setting up a nested custom config. Great job!

    Phản hồi bởi Andy Warren | Tháng Ba 19, 2008 | Trả lời

  3. [...] AM: fmavituna: waiting for bbq to be ready Custom configuration for NET 2.0 « Incomplete Leo Xml Serializer Section Handler Class From Config for C#.NET – wiki.webgear.co.nz [...]

    Pingback bởi ForumKral.Org » Blog Archive » Günlük Maceralar - 18.05.08 | Tháng Năm 27, 2008 | Trả lời

  4. Thanks Sasha.

    I got one question about :
    what is my configuration file like :

    I have EmployeeChildNode but no EmployeeChildNodes.

    How to create EmployeeChildNode ?
    Thanks for reply.

    Phản hồi bởi Calvin | Tháng Mười Hai 17, 2008 | Trả lời

  5. Unfortunately this code doesn’t work. It doesn’t do anything. I’m pretty sure I’ve configured it right, but it simply fails to even try loading the section.

    How frustrating when someone posts something that is incomplete or inaccurate.

    Based on how difficult it is to get this declarative stuff to work, I’m not convinced it should be used at all. Getting it to work is virtually impossible. If you change it then presumably it is going to break again.

    After two DAYS of trying to do something SIMPLE, I’m having to give up. I suggest you don’t waste time trying something that should be easy, but for which there is not a single working example on the web. Nobody’s code for loading a collection works.

    Phản hồi bởi Andrew H | Tháng Hai 3, 2009 | Trả lời

  6. [...] AM: fmavituna: waiting for bbq to be ready Custom configuration for NET 2.0 « Incomplete Leo Xml Serializer Section Handler Class From Config for C#.NET – wiki.webgear.co.nz [...]

    Pingback bởi iS34.Net Güncel Haberler » Günlük Maceralar - 18.05.08 | Tháng Ba 21, 2009 | Trả lời

  7. I have on my own analyzed and resulted in the cpa test review from Morgan to be the highest quality.

    Phản hồi bởi Bret Evensen | Tháng Chín 16, 2011 | Trả lời

  8. Works great thanks for the tips

    Phản hồi bởi moggahooller | Tháng Mười Hai 29, 2011 | Trả lời


Gửi phản hồi

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Thay đổi )

Twitter picture

You are commenting using your Twitter account. Log Out / Thay đổi )

Facebook photo

You are commenting using your Facebook account. Log Out / Thay đổi )

Google+ photo

You are commenting using your Google+ account. Log Out / Thay đổi )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: