This quick tip shows how to manage a parameterization in .NET 2.0 and higher. It's useful for someone who already knows it and who is just looking for the exact solution. Just go through the headlines, choose the case and use it.
Simple configuration section – Imperative approach
Configuration file:
="1.0" ="utf-8"
<configuration>
<configSections>
<section
name="SocketConfig"
type="Sample2.SocketConfiguration, Sample2"
/>
</configSections>
<SocketConfig ProtocolType="Udp" SocketType="Dgram" />
</configuration>
Code:
namespace Sample2 {
public class SocketConfiguration : ConfigurationSection {
#region Variables
private ConfigurationPropertyCollection _properties;
private static readonly ConfigurationProperty _protocolType = new ConfigurationProperty(
"ProtocolType", typeof(ProtocolType), "Tcp");
private static readonly ConfigurationProperty _socketType = new ConfigurationProperty(
"SocketType", typeof(SocketType), "Stream");
#endregion
#region Properties
public ProtocolType ProtocolType {
get {
return (ProtocolType)this[_protocolType];
}
set {
this[_protocolType] = value;
}
}
public SocketType SocketType {
get {
return (SocketType)this[_socketType];
}
set {
this[_socketType] = value;
}
}
protected override ConfigurationPropertyCollection Properties {
get {
return _properties;
}
}
#endregion
#region Methods
public SocketConfiguration() {
_properties = new ConfigurationPropertyCollection();
Properties.Add(_protocolType);
Properties.Add(_socketType);
}
#endregion
}
}
Simple configuration section – Declarative approach
Configuration file:
="1.0" ="utf-8"
<configuration>
<configSections>
<section
name="SocketConfig"
type="Sample3.SocketConfiguration, Sample3"
/>
</configSections>
<SocketConfig ProtocolType="Udp" SocketType="Dgram" />
</configuration>
Code:
namespace Sample3 {
public class SocketConfiguration : ConfigurationSection {
#region Variables
private const string _protocolType = "ProtocolType";
private const string _socketType = "SocketType";
#endregion
#region Properties
[ConfigurationProperty(_protocolType, DefaultValue=ProtocolType.Tcp)]
public ProtocolType ProtocolType {
get {
return (ProtocolType)this[_protocolType];
}
set {
this[_protocolType] = value;
}
}
[ConfigurationProperty(_socketType, DefaultValue=SocketType.Stream)]
public SocketType SocketType {
get {
return (SocketType)this[_socketType];
}
set {
this[_socketType] = value;
}
}
#endregion
#region Methods
public SocketConfiguration() {
}
#endregion
}
}
Configuration section with a custom type
Configuration file:
="1.0" ="utf-8"
<configuration>
<configSections>
<section
name="WinConfig"
type="Sample4.WindowConfiguration, Sample4"
/>
</configSections>
<WinConfig Position="22, 42" />
</configuration>
Code:
namespace Sample4 {
public class WindowConfiguration : ConfigurationSection {
#region Variables
#endregion
#region Properties
[ConfigurationProperty("Position", DefaultValue="1, 1", IsRequired=true)]
public Position Position {
get {
return (Position)this["Position"];
}
set {
this["Position"] = value;
}
}
#endregion
#region Methods
public WindowConfiguration() {
}
#endregion
}
[TypeConverter(typeof(PositionConverter))]
public class Position {
#region Variables
private int _xPosition;
private int _yPosition;
#endregion
#region Properties
public int XPosition {
get { return _xPosition; }
set { _xPosition = value; }
}
public int YPosition {
get { return _yPosition; }
set { _yPosition = value; }
}
#endregion
#region Methods
public Position(int xPosition, int yPosition) {
XPosition = xPosition;
YPosition = yPosition;
}
#endregion
}
public class PositionConverter : ConfigurationConverterBase {
public PositionConverter() {
}
public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value) {
string[] array = value.ToString().Split(',');
return new Position(int.Parse(array[0].Trim()), int.Parse(array[1].Trim()));
}
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type destinationType) {
Position w = (Position)value;
return string.Format("{0}, {1}", w.XPosition, w.YPosition);
}
}
}
Configuration section with a custom validator:
Configuration file:
="1.0" ="utf-8"
<configuration>
<configSections>
<section
name="WinConfig"
type="Sample6.WindowConfiguration, Sample6"
/>
</configSections>
<WinConfig Position="0, 42" />
</configuration>
Code:
namespace Sample6 {
public class WindowConfiguration : ConfigurationSection {
#region Variables
#endregion
#region Properties
[ConfigurationProperty("Position", DefaultValue="6, 3", IsRequired=true)]
[PositionValidator(1, 100, 2, 200)]
public Position Position {
get {
return (Position)this["Position"];
}
set {
this["Position"] = value;
}
}
#endregion
#region Methods
public WindowConfiguration() {
}
#endregion
}
[TypeConverter(typeof(PositionConverter))]
public class Position {
#region Variables
private int _xPosition;
private int _yPosition;
#endregion
#region Properties
public int XPosition {
get { return _xPosition; }
set { _xPosition = value; }
}
public int YPosition {
get { return _yPosition; }
set { _yPosition = value; }
}
#endregion
#region Methods
public Position(int xPosition, int yPosition) {
XPosition = xPosition;
YPosition = yPosition;
}
#endregion
}
public class PositionConverter : ConfigurationConverterBase {
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
string[] array = value.ToString().Split(',');
return new Position(int.Parse(array[0].Trim()), int.Parse(array[1].Trim()));
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
Position w = (Position)value;
return string.Format("{0}, {1}", w.XPosition, w.YPosition);
}
}
public class PositionValidator : ConfigurationValidatorBase {
#region Variables
private int _xMin;
private int _xMax;
private int _yMin;
private int _yMax;
#endregion
#region Properties
#endregion
#region Methods
public PositionValidator(int xMin, int xMax, int yMin, int yMax) {
_xMax = xMax;
_xMin = xMin;
_yMax = yMax;
_yMin = yMin;
}
public override bool CanValidate(Type type) {
return type == typeof(Position);
}
public override void Validate(object value) {
Position p = (Position)value;
if (!(p.XPosition >= _xMin && p.XPosition <= _xMax &&
p.YPosition >= _yMin && p.YPosition <= _yMax))
throw new ConfigurationErrorsException();
}
#endregion
}
[AttributeUsage(AttributeTargets.Property)]
public class PositionValidatorAttribute : ConfigurationValidatorAttribute {
#region Variables
private int _xMin;
private int _xMax;
private int _yMin;
private int _yMax;
#endregion
#region Properties
#endregion
#region Methods
public PositionValidatorAttribute(int xMin, int xMax, int yMin, int yMax) {
_xMax = xMax;
_xMin = xMin;
_yMax = yMax;
_yMin = yMin;
}
public override ConfigurationValidatorBase ValidatorInstance {
get {
return new PositionValidator(_xMin, _yMax, _yMin, _yMax);
}
}
#endregion
}
}
Configuration collection:
Configuration file:
="1.0" ="utf-8"
<configuration>
<configSections>
<section name="ItemConfiguration" type="SimpleCollectionInConfigurationFile.ItemSettings, SimpleCollectionInConfigurationFile" />
</configSections>
<ItemConfiguration>
<Items>
<add key="1" someValue="a" />
<add key="2" someValue="b" />
<add key="3" someValue="c" />
</Items>
</ItemConfiguration>
</configuration>
Code:
namespace SimpleCollectionInConfigurationFile {
public class ItemConfigurationElement : ConfigurationElement {
[ConfigurationProperty("key", IsKey = true)]
public string Key {
get { return (string) base["key"]; }
set { base["key"] = value; }
}
[ConfigurationProperty("someValue")]
public string SomeValue {
get { return (string) base["someValue"]; }
set { base["someValue"] = value; }
}
public ItemConfigurationElement() {
}
}
public class ItemCollection : ConfigurationElementCollection {
protected override ConfigurationElement CreateNewElement() {
return new ItemConfigurationElement();
}
protected override object GetElementKey(ConfigurationElement element) {
return ((ItemConfigurationElement)element).Key;
}
}
public class ItemSettings : ConfigurationSection {
[ConfigurationProperty("Items", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(ItemCollection))]
public ItemCollection Items {
get {
return (ItemCollection)base["Items"];
}
}
}
}
Example of use:
ItemSettings settings = (ItemSettings)ConfigurationManager.GetSection("ItemConfiguration");
foreach (ItemConfigurationElement element in settings.Items)
{
Console.WriteLine(string.Format("Key={0} Value={1}",
element.Key,
element.SomeValue));
}