How can I get and use an attribute set in the parent ConfigurationSection in the descendent CustomSetting element? I need this attribute when the CustomSetting element is returning the Value property.
I want to format the App.config like this:
<CustomSettings someProperty="foo">
<CustomSetting key="bar" value="fermeneba" />
<CustomSetting key="laa" value="jubaduba" />
</CustomSettings>
I have the code working, except that I cannot find a way to access the someProperty attribute from the CustomSetting class. The only way that I've found, so far, is to format the configuration like this, which is messy:
<CustomSettings>
<CustomSetting someProperty="foo" key="bar" value="fermeneba" />
<CustomSetting someProperty="foo" key="laa" value="jubaduba" />
</CustomSettings>
Achieving this is more difficult than it should be since the System.Configuration API doesn't allow you to navigate from a ConfigurationElement
to its parent. Hence, if you want to access some information that on a parent element you need to create that relationship manually. I've put together a sample implementation that does that for the config snippet in your question:
public class CustomSettingsSection : ConfigurationSection
{
[ConfigurationProperty("someProperty", DefaultValue="")]
public string SomeProperty
{
get { return (string)base["someProperty"]; }
set { base["someProperty"] = value; }
}
[ConfigurationProperty("", IsDefaultCollection = true)]
public CustomSettingElementCollection Elements
{
get
{
var elements = base[""] as CustomSettingElementCollection;
if (elements != null && elements.Section == null)
elements.Section = this;
return elements;
}
}
}
public class CustomSettingElementCollection : ConfigurationElementCollection
{
internal CustomSettingsSection Section { get; set; }
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
public CustomSettingElement this[string key]
{
get { return BaseGet(key) as CustomSettingElement; }
}
protected override ConfigurationElement CreateNewElement()
{
return new CustomSettingElement { Parent = this };
}
protected override object GetElementKey(ConfigurationElement element)
{
return (element as CustomSettingElement).Key;
}
protected override string ElementName
{
get { return "customSetting"; }
}
}
public class CustomSettingElement : ConfigurationElement
{
internal CustomSettingElementCollection Parent { get; set; }
public string SomeProperty
{
get
{
if (Parent != null && Parent.Section != null)
return Parent.Section.SomeProperty;
return default(string);
}
}
[ConfigurationProperty("key", IsKey = true, IsRequired = true)]
public string Key
{
get { return (string)base["key"]; }
set { base["key"] = value; }
}
[ConfigurationProperty("value", DefaultValue = "")]
public string Value
{
get { return (string)base["value"]; }
set { base["value"] = value; }
}
}
You can see that the CustomSettingElementCollection
has a Section
property which gets set in the section's Elements
getter. The CustomSettingElement
, in turn, has a Parent
property which gets set in the collection's CreateNewElement()
method.
That then makes it possible to walk up the relationship tree and to add a SomeProperty
property to the element even though this one doesn't correspond to an actual ConfigurationProperty on that element.
Hope that gives you an idea how to solve your problem!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With