andrew4582

Serializable Dictionary

Aug 1st, 2012
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.83 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using System.Xml.Serialization;
  5. using System.Diagnostics;
  6.  
  7. namespace Core
  8. {
  9.     /// <summary>
  10.     /// Dictionary that can serialize/deserialize into a xml document
  11.     /// </summary>
  12.     [XmlRoot("dictionary")]
  13.     [Serializable]
  14.     public class SerializableDictionary<TKey,TValue>:Dictionary<TKey,TValue>,IXmlSerializable
  15.     {
  16.  
  17.         #region Constructor
  18.         public SerializableDictionary()
  19.         {
  20.         }
  21.  
  22.         public SerializableDictionary(IDictionary<TKey,TValue> dictionary)
  23.             : base(dictionary)
  24.         {
  25.         }
  26.  
  27.         #endregion
  28.  
  29.         #region IXmlSerializable Members
  30.  
  31.         public System.Xml.Schema.XmlSchema GetSchema()
  32.         {
  33.             return null;
  34.         }
  35.  
  36.         public void ReadXml(System.Xml.XmlReader reader)
  37.         {
  38.             if(reader.IsEmptyElement)
  39.                 return;
  40.  
  41.             XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
  42.             Dictionary<Type,XmlSerializer> valueSerializersDict = new Dictionary<Type,XmlSerializer>();
  43.            
  44.             while(!reader.EOF)
  45.             {
  46.                
  47.                 reader.ReadToFollowing("item");
  48.                    
  49.                 string typeName = null;
  50.  
  51.                 if(reader.HasAttributes)
  52.                 {
  53.                     bool found = reader.MoveToAttribute("type");
  54.                     if(found)
  55.                     {
  56.                         reader.ReadAttributeValue(); //<item type='' ...
  57.                         typeName = reader.Value;
  58.                     }
  59.                 }
  60.                 Type vtype = typeof(TValue);
  61.                 if(typeName != null)
  62.                 {
  63.                     vtype = Type.GetType(typeName);
  64.                 }
  65.  
  66.                 TKey key = default(TKey);
  67.                 TValue value = default(TValue);
  68.  
  69.                 if(reader.ReadToFollowing("key")) //<item><key...
  70.                 {
  71.                     object rawKey = reader.ReadString();
  72.                     if(typeof(TKey) == typeof(string))
  73.                         key = (TKey)rawKey;
  74.                     else
  75.                         key = (TKey)Convert.ChangeType(rawKey,typeof(TKey));
  76.                 }
  77.  
  78.                 if(!reader.ReadToFollowing("value")) //<item><value...
  79.                     break; //no value; bad xml; so leave
  80.  
  81.                 if(vtype.IsClass && vtype != typeof(string))
  82.                 {
  83.                     XmlSerializer vSerializer = null;
  84.  
  85.                     //cache serializers
  86.                     if(!valueSerializersDict.TryGetValue(vtype,out vSerializer))
  87.                     {
  88.                         vSerializer = new XmlSerializer(vtype);
  89.                         valueSerializersDict.Add(vtype,vSerializer);
  90.                     }
  91.  
  92.                     string rawxml = reader.ReadInnerXml();
  93.                     if(!string.IsNullOrEmpty(rawxml))
  94.                     {
  95.                         //deserialize value's type
  96.                         object rawvalue = null;
  97.                         using(System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(rawxml)))
  98.                         {
  99.                             System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream,System.Text.Encoding.UTF8);
  100.                             rawvalue = vSerializer.Deserialize(memoryStream);
  101.                         }
  102.  
  103.                         value = (TValue)rawvalue;
  104.                     }
  105.                 }
  106.                 else
  107.                 {
  108.                     object rawValue = reader.ReadString();
  109.                     if(typeof(TValue) == typeof(string))
  110.                         value = (TValue)rawValue;
  111.                     else
  112.                         value = (TValue)Convert.ChangeType(rawValue,vtype);
  113.                 }
  114.  
  115.                 //add to dictionary
  116.                 this.Add(key,value);
  117.  
  118.                 //skip any empty space
  119.                 reader.MoveToContent();
  120.  
  121.                 if(reader.IsEmptyElement)
  122.                     break;
  123.             }
  124.         }
  125.  
  126.         public void WriteXml(System.Xml.XmlWriter writer)
  127.         {
  128.             XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
  129.             XmlSerializer objectSerializer = new XmlSerializer(typeof(object));
  130.  
  131.             Dictionary<Type,XmlSerializer> serializerDict = new Dictionary<Type,XmlSerializer>();
  132.             serializerDict.Add(typeof(TValue),new XmlSerializer(typeof(TValue)));
  133.  
  134.             System.Xml.Serialization.XmlSerializerNamespaces emptyNamespace = new System.Xml.Serialization.XmlSerializerNamespaces();
  135.             emptyNamespace.Add(string.Empty,string.Empty);
  136.  
  137.             foreach(TKey key in this.Keys)
  138.             {
  139.                 object value = this[key];
  140.                 Type vtype = value.GetType();
  141.  
  142.                 string keyAsString = key.ToString();
  143.  
  144.                 //start writing item element with type attribute <item type='valuetype'>
  145.                 writer.WriteStartElement("item");
  146.                 if(vtype.IsClass && vtype != typeof(string))
  147.                     writer.WriteAttributeString("type",vtype.AssemblyQualifiedName);
  148.                 else
  149.                     writer.WriteAttributeString("type",vtype.FullName);
  150.  
  151.                 //start writing key element
  152.                 writer.WriteStartElement("key"); //<key>key value</key>
  153.                 writer.WriteString(keyAsString);
  154.                 writer.WriteEndElement();
  155.  
  156.  
  157.                 if(vtype.IsClass && vtype != typeof(string))
  158.                 {
  159.                     XmlSerializer vSerializer = null;
  160.                     if(!serializerDict.TryGetValue(vtype,out vSerializer))
  161.                     {
  162.                         vSerializer = new XmlSerializer(vtype);
  163.                         serializerDict.Add(vtype,vSerializer);
  164.                     }
  165.                     writer.WriteStartElement("value"); //<value><valueElement></valueElement></value>
  166.                     vSerializer.Serialize(writer,value,emptyNamespace);
  167.                     writer.WriteEndElement();
  168.                 }
  169.                 else
  170.                 {
  171.                     writer.WriteStartElement("value"); //<value>value</value>
  172.                     writer.WriteString(value.ToString());
  173.                     writer.WriteEndElement();
  174.                 }
  175.                 //end write item element
  176.                 writer.WriteEndElement();
  177.             }
  178.         }
  179.  
  180.         #endregion
  181.     }
  182. }
Advertisement
Add Comment
Please, Sign In to add comment