Been using this a fair bit recently, allows complete control over the way a class serializes to XML – especially useful when using Dictionaries!
public class CountryDictionary : DictionaryBase, IXmlSerializable
{
public bool requiresSave = false;
public Country this[long key]
{
get { return ((Country) Dictionary[key]); }
set { Dictionary[key] = value; }
}
public ICollection Keys
{
get { return (Dictionary.Keys); }
}
public ICollection Values
{
get { return (Dictionary.Values); }
}
public void Add(long key, Country value)
{
Dictionary.Add(key, value);
}
public bool Contains(long key)
{
return (Dictionary.Contains(key));
}
public void Remove(long key)
{
Dictionary.Remove(key);
}
protected override void OnInsert(Object key, Object value)
{
if (key.GetType() != typeof (long))
throw new ArgumentException("key must be of type long.", "key");
if (value.GetType() != typeof (Country))
throw new ArgumentException("value must be of type Country.", "value");
}
#region IXmlSerializable Members
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("Countries");
foreach(Country country in this.Values)
{
writer.WriteStartElement("Country");
writer.WriteAttributeString("iso3", country.Iso3);
writer.WriteAttributeString("id", country.ObjectId.ToString());
writer.WriteAttributeString("name", country.Name);
writer.WriteAttributeString("active", country.Active.ToString());
writer.WriteAttributeString("restricted", country.Restricted.ToString());
writer.WriteAttributeString("shippingZone", country.ShippingZoneId.ToString());
writer.WriteEndElement();
}
writer.WriteEndElement();
}
public System.Xml.Schema.XmlSchema GetSchema()
{
// TODO: Add CountryDictionary.GetSchema implementation
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
bool saveNeeded = false;
while (reader.Read())
{
if (reader.IsStartElement("Country"))
{
long objectId = reader.GetAttribute("id") != null ? long.Parse(reader.GetAttribute("id") ) : 0;
Country country = new Country();
string name = reader.GetAttribute("name");
string iso3 = reader.GetAttribute("iso3");
bool active = reader.GetAttribute("active") != null ? bool.Parse(reader.GetAttribute("active")) : true;
bool restricted = reader.GetAttribute("restricted") != null ? bool.Parse(reader.GetAttribute("restricted")) : false;
long shippingZoneId = reader.GetAttribute("shippingZone") != null ? long.Parse(reader.GetAttribute("shippingZone")) : 0;
country.Name = name;
country.ObjectId = objectId;
country.Iso3 = iso3;
country.Active = active;
country.Restricted = restricted;
country.ShippingZoneId = shippingZoneId;
if(country.ObjectId ==0)
{
country.Save();
saveNeeded = true;
}
this.Add(country.ObjectId, country);
}
}
this.requiresSave = saveNeeded;
}
#endregion
}
So, as you can see it’s pretty simple, just letting you treat the serialization process as saving out a standard XML file…the actual serialization code is simple too:
/// <summary>
/// Summary description for XmlCountryProvider.
/// </summary>
public class XmlCountryProvider
{
private static string filePath = Global.Config.CountryFile;
private XmlCountryProvider()
{
}
public static CountryDictionary Load()
{
XmlSerializer xser = new XmlSerializer(typeof(CountryDictionary));
CountryDictionary fd = null;
if(File.Exists(filePath))
{
using(TextReader tr = File.OpenText(filePath))
{
fd = (CountryDictionary) xser.Deserialize(tr);
}
}
return fd;
}
public static void Save(CountryDictionary fd)
{
XmlSerializer xser = new XmlSerializer(typeof(CountryDictionary));
using(TextWriter tw = File.CreateText(filePath))
{
xser.Serialize(tw,fd);
}
}
}
So this essentially lets me very quickly save and load info from disk – not great when you need ‘db-type’ operations but it just rules when you need something to be easily editable…