.NET 2.0 offers very powerful configuration mechanism, which allows you to build you custom configuration sections,
elements etc. Unfortunately, many details are very poor documented. In this post I will shortly show some interesting details.
For example, imagine you want to build your own section, which can be configured as shown below:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="MySection" type="MyLibrary.MySectionClass, MySectionAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </configSections> … |
The shown configuration snippet defines the configuration section "MySection" implemented in the type
MyLibrary.MySectionClass and assembly MySectionAssembly. Additionally, let's say the configuration
should look as shown in the next example:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="MySection" type="MyLibrary.MySectionClass, MySectionAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </configSections> . . . <MySection> <dynamicEndpoints> <dynamicEndpoint name="MyTestEndpoint1" behaviorConfiguration="SomeBehavior"/> <dynamicEndpoint name="MyTestEndpoint2" behaviorConfiguration="SomeBehavior"/> </dynamicEndpoints> </MySection > |
The section should contain a property dynamicEndpoints of type list, which contain multiple elements dynamicEndpoint.
The element dynamicEndpoint contains two custom attributes: name and behaviorConfiguration.
Next example shows how to implement this scenario. First that have to be done is to implement the class which is serialized
as section element. In this case MySection.
using System; using System.Collections.Generic; using System.Text; using System.Configuration;
namespace MyLibrary { public class MySectionClass : ConfigurationSection { [ConfigurationProperty("dynamicEndpoints", IsRequired = true)] public DynamicEndpointElementCollection DynamicEndpoints { get { return (DynamicEndpointElementCollection) base["dynamicEndpoints"]; } } } } |
This example implements the section class, which has one property of type DynamicEndpointElementCollection.
The interesting thing at this place is attribute IsRequired. This specifies whether the attribute is mandatory or optional one.
In the next step the collection dynamicEndpoints has to be implemented. Next example is all you have to implement.
using System; using System.Collections.Generic; using System.Text; using System.Configuration; namespace MyLibrary {
[ConfigurationCollection(typeof(DynamicEndpointConfigElement), AddItemName = "dynamicEndpoint")] public class DynamicEndpointElementCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new DynamicEndpointConfigElement(); } protected override Object GetElementKey(ConfigurationElement element) { return ((DynamicEndpointConfigElement)element).Name; } } } |
It is important to notice the attribute AddItemName. This attribute defines the name of the element as it will
appear in the list. Without of setting of this attribute the configuration would look a little different:
<add name="Uri" behaviorConfiguration=" />
As you see, the element is in this case some kind of untyped configuration element. Such elements are useful for untyped information
like properties which cannot be determined at the time design time.
At the end the element have to be implemented as shown in the next example.
using System; using System.Collections.Generic; using System.Text; using System.Configuration; namespace MyLibrary
{ public class DynamicEndpointConfigElement : ConfigurationElement { [ConfigurationProperty("behaviorConfiguration", IsRequired = true)] public string BehaviorConfiguration { get { return (string)base["behaviorConfiguration"]; } } [ConfigurationProperty("name", IsRequired = true)] public string Name { get { return (string)base["name"]; } } } } |
An intersting example can be donloaded
here.
Posted
Feb 07 2007, 10:55 PM
by
Damir Dobric