public void
WriteConfig(object o)
{
//Get
all public and non-public members
MemberInfo[]
mia=o.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic);
//get
or create the XML document
XmlDocument
doc=new XmlDocument();
XmlNode
section;
try
{
doc.Load(_configFile);
}
catch(FileNotFoundException)
{
//file
doesn't exist...
XmlTextWriter
tw=new
XmlTextWriter(_configFile,Encoding.Default);
tw.Formatting=Formatting.Indented;
tw.WriteStartDocument();
tw.WriteStartElement("EasyConfig");
tw.WriteStartElement(_sectionName);
tw.WriteEndElement();
tw.WriteEndElement();
tw.WriteEndDocument();
tw.Close();
doc.Load(_configFile);
}
finally
{
XmlNodeList
nl=doc.GetElementsByTagName(_sectionName);
section=nl.Item(0);
}
foreach(MemberInfo
mi in mia)
{
if(mi.MemberType==MemberTypes.Field)
{//check
to see if it's declared as configurable
object[]
ca=mi.GetCustomAttributes(typeof(ConfigurableAttribute),false);
if(ca.Length>0)
{//there
will be only one really...
//set
up the node in the config doc
XmlNode
nd=section.SelectSingleNode(mi.Name);
if(nd==null)
{
//if the node isn't already in the file, create it
section.AppendChild(doc.CreateElement(mi.Name));
nd=section.SelectSingleNode(mi.Name);
}
//now
get all the configurable properties of the current object
object[]
properties=mi.GetCustomAttributes(typeof(ConfigurablePropertyAttribute),false);
foreach(ConfigurablePropertyAttribute
cpa in properties)
{
XmlNode pd=nd.SelectSingleNode(cpa.PropertyName);
if(pd==null)
{
nd.AppendChild(doc.CreateElement(cpa.PropertyName));
pd=nd.SelectSingleNode(cpa.PropertyName);
}
//write the value to the file...
FieldInfo fi=mi as FieldInfo;
//get the instance of the private field..
(scary stuff!)
object obj=fi.GetValue(o);
//get the member info for the property of
the private field we're interrogating
MemberInfo[] pa=obj.GetType().GetMember(cpa.PropertyName,MemberTypes.Property,BindingFlags.Public
| BindingFlags.Instance);
if(pa.Length>0)
{
//make sure it's a propertyinfo
PropertyInfo po=pa[0] as
PropertyInfo;
//if it is..
if(po!=null)
{
//get the TypeConverter.
TypeConverter tc=TypeDescriptor.GetConverter(po.PropertyType);
if(tc!=null
&& tc.CanConvertTo(typeof(string)))
pd.InnerXml=(string)tc.ConvertTo(po.GetValue(obj,null),typeof(string));
}
}
}
}
}
}
//now
for the configurable properties of the owner class
object[]
props = o.GetType().GetCustomAttributes(typeof(ConfigurablePropertyAttribute),false);
if(props.Length>0)
{
//first
get or create the entry in the section
XmlNode
ownerNode=section.SelectSingleNode(o.GetType().Name);
if(ownerNode==null)
{
section.AppendChild(doc.CreateElement(o.GetType().Name));
ownerNode=
section.SelectSingleNode(o.GetType().Name);
}
foreach(ConfigurablePropertyAttribute
cpa in props)
{
//get
the property.
PropertyInfo
pi=o.GetType().GetProperty(cpa.PropertyName);
if(pi!=null)
{
//get
or create an entry
XmlNode
pEntry=ownerNode.SelectSingleNode(cpa.PropertyName);
if(pEntry==null)
{
ownerNode.AppendChild(doc.CreateElement(cpa.PropertyName));
pEntry = ownerNode.SelectSingleNode(cpa.PropertyName);
}
//get
the type converter
TypeConverter
tc=TypeDescriptor.GetConverter(pi.PropertyType);
if(tc!=null
&& tc.CanConvertTo(typeof(string)))
{
pEntry.InnerXml=(string)tc.ConvertTo(pi.GetValue(o,null),typeof(string));
}
}
}
}
doc.Save(_configFile);
}