Lets say I have the following configuration section....
<yak>
<whaa hello="world" />
</yak>
<yak>
<whaa hello="world" blot="1" />
</yak>
Because the second <whaa>
element has the extra attribute on it I want to map it to a sub type of the the type that's mapped to the first <whaa>
element.
So how do I get polymorphic binding?
Here's one approach by using a programmatic solution which overrides the OnDeserializeUnrecognizedElement
method of the ConfigurationSection
class. The base and child configuration element classes:
public class Whaa : ConfigurationElement
{
[ConfigurationProperty("hello", IsRequired = true)]
public string Hello
{
get
{
return base["hello"] as string;
}
set
{
base["hello"] = value;
}
}
}
public class WhaaChild : Whaa
{
[ConfigurationProperty("blot", IsRequired = true)]
public string Blot
{
get
{
return base["blot"] as string;
}
set
{
base["blot"] = value;
}
}
}
The configuration section class:
public class Yak : ConfigurationSection
{
public Whaa MyProperty;
protected override bool
OnDeserializeUnrecognizedElement(string elementName, XmlReader reader)
{
if (elementName == "whaa")
{
try
{
var hello = reader.GetAttribute("hello");
if (hello != null)
{
var blot = reader.GetAttribute("blot");
if (blot != null)
{
MyProperty = new WhaaChild()
{
Blot = blot,
Hello = hello
};
}
else
{
MyProperty = new Whaa()
{
Hello = hello
};
}
}
}
catch (Exception)
{
// TODO: add exception handling
}
}
return true;
}
}
The sample usage:
var yakSectionSettings = (Yak)ConfigurationManager.GetSection("yak");
And the configuration markup:
<configSections>
<section name="yak" type="Yak, MyApplication"/>
</configSections>
You may use now either:
<yak>
<whaa hello="world"/>
</yak>
for getting a Whaa
object, or:
<yak>
<whaa hello="world" blot="1"/>
</yak>
for getting a WhaaChild
object at runtime.