I'm trying to create some typed configuration similar to the following snippet...
<logging application="Global Application Name">
<defaultLogger name="default" genericOption="XXX" specificOptionYYY="yyy" />
<defaultLogger name="notAsDefault" genericOption="AAA" specificOptionYYY="bbb" />
<anotherDefaultLogger name="anotherDefault" genericOption="ZZZ" specificOptionWWW="www" />
</logging>
At the root would be a LoggerSettings class that would contain the application
property and a collection of LoggingConfigurationElement
s.
The LoggingConfigurationElement would contain the genericOption
property.
There would then be two specific sub-classes that would be created containing the specificOptionYYY
and specificOptionWWW
.
How would I then go about matching and instantiating the correct sub-class of configuration element at run time based on the element's name?
The trick was to override the OnDeserializeUnrecognizedElement
method and dynamically create the configuration element required, and deserialise it manually.
override protected bool OnDeserializeUnrecognizedElement (string elementName, System.Xml.XmlReader
{
if (sNames.ContainsKey (elementName))
{
var elementType = sNames[elementName];
if (elementType != null)
{
var element = Activator.CreateInstance (elementType) as LoggerConfigurationElement;
if (element != null)
{
element.DeserializeElementForConfig (reader, false);
BaseAdd (element);
}
}
return true;
}
return base.OnDeserializeUnrecognizedElement (elementName, reader);
}
In this example, I've pre-built the list of valid element names using a combination of reflection and configuration (yes, more configuration!) so I know up-front if the supplied element is a valid one.