programatically save a ConfigurationElementCollection with attributes

  • Thread starter Thread starter Eric
  • Start date Start date
E

Eric

Hi Folks,

I wrote a custom configuration element which is
ConfigurationElementCollection with attributes. The configuration
section does look like this:

<rules name="Personal Rules">
<rule name="Rule 01" order="1" />
<rule name="Rule 02" order="2" />
</rules>

I read the attributes overriding the
OnDeserializeUnrecognizedAttribute method with no problem, but I can't
find a methos to actually Serialize the collection attribute, which
limits the way I can programmatically update the configuration.

Does anyone how can I do programmatically save this attribute?

Thanks in advance.
 
Hi,

You might want to use the built in configuration support for this.
Example :
namespace RuleConfig
{
public class RuleElement : ConfigurationElement
{
private static readonly ConfigurationProperty _order;
private static readonly ConfigurationProperty _name;
private static readonly ConfigurationPropertyCollection _properties;
static RuleElement()
{
_order = new ConfigurationProperty("order", typeof(int), null,
ConfigurationPropertyOptions.IsRequired);
_name = new ConfigurationProperty("name", typeof(string), null,
ConfigurationPropertyOptions.IsRequired);
_properties = new ConfigurationPropertyCollection();
_properties.Add(_order);
_properties.Add(_name);
}
public string Name
{
get { return (string)base[_name]; }
set { base[_name] = value; }
}
public int Order
{
get { return (int)base[_order]; }
set { base[_order] = value; }
}
protected override ConfigurationPropertyCollection Properties
{
get
{
return _properties;
}
}
}
[ConfigurationCollection(typeof(RuleElement), CollectionType =
ConfigurationElementCollectionType.BasicMap, AddItemName = "rule")]
public class RuleCollection : ConfigurationElementCollection
{
public void Add(RuleElement element)
{
base.BaseAdd(element);
}
protected override ConfigurationElement CreateNewElement()
{
return new RuleElement();
}
protected override object GetElementKey(ConfigurationElement
element)
{
return ((RuleElement)element).Order;
}
protected override string ElementName
{ get { return "rule"; } }
public override ConfigurationElementCollectionType CollectionType
{ get { return ConfigurationElementCollectionType.BasicMap; } }
}
public class RuleSection : ConfigurationSection
{
private static readonly ConfigurationProperty _rules;
private static readonly ConfigurationPropertyCollection _properties;
static RuleSection()
{
_rules = new ConfigurationProperty(null, typeof(RuleCollection),
null, ConfigurationPropertyOptions.IsDefaultCollection);
_properties = new ConfigurationPropertyCollection();
_properties.Add(_rules);
}
protected override ConfigurationPropertyCollection Properties
{
get
{
return _properties;
}
}
public RuleCollection Rules
{
get { return (RuleCollection)base[_rules]; }
}
}
}
-----------------------------------Example app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section type="RuleConfig.RuleSection, RuleConfig" name="rules"/>
</configSections>
<rules>
<rule order="1" name="name1"/>
<rule order="2" name="name2"/>
</rules>
</configuration>
----------------------------------Example of use
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
RuleSection section = config.GetSection("rules") as RuleSection;
if (section != null)
{
//read
foreach (RuleElement rule in section.Rules)
System.Console.WriteLine(string.Format("{0,5}:{1}", rule.Order,
rule.Name));
//modify
section.Rules.Add(new RuleElement() { Order = 8, Name = "name8" });
config.Save(ConfigurationSaveMode.Modified);
}


Hope You find this useful.
-Zsolt
 
    public class RuleElement : ConfigurationElement
    {
        private static readonly ConfigurationProperty _order;
        private static readonly ConfigurationProperty _name;
        private static readonly ConfigurationPropertyCollection _properties;
-Zsolt

Nice!! thanks Miher. I was declaring the property trought the use of
ConfigurationProperty attribute but I did'nt realize that in the case
of a collection, I still have to create the ConfigurationProperty by
hand.

One final question, I saw examples of custom configuration where the
property is a static variable, just like yours, and other where they
are instance fields. Is it safe to declare them as static?

tahnks a lot.
 
Hi,
Nice!! thanks Miher. I was declaring the property trought the use of
ConfigurationProperty attribute but I did'nt realize that in the case
of a collection, I still have to create the ConfigurationProperty by
hand.
You can do it with attributes also, instead of declaring the
ConfigurationProperties, the two are the same.
One final question, I saw examples of custom configuration where the
property is a static variable, just like yours, and other where they
are instance fields. Is it safe to declare them as static?
These fields only describe the properties so i dont see anything against
declaring those as static variables (and with that we also prevent them
being cloned to every instance.)

It just came to my mind that i have read a really cool article about this,
You might want to check it out. :
http://www.codeproject.com/KB/dotnet/mysteriesofconfiguration.aspx

Hope You find this useful.
-Zsolt
 
Back
Top