2010-11-22 19 views
1

J'ai une variable Dictionary, le programme lit les fichiers XML, puis instancie les objets stockés dans la variable Dictionary par type pour les performances. Je voudrais stocker la variable Dictionary dans memcache pour la réutiliser, mais comme la variable Dictionary et les objets instanciés sont des types de référence, lorsque j'utilise des objets instanciés pour modifier certaines valeurs, la valeur de cache de memcache a également changé.Comment sérialiser/désérialiser une variable Dictionary?

Code comme suit. La variable de dictionnaire et la variable de classe XPathNavigator ne peuvent pas être sérialisées. Comment puis-je sérialiser/désérialiser ou obtenir un effet similaire? Merci.

namespace ObjectReference 
{  
    public interface IMyObject 
    { 
     int Id { get; set; } 
     string Url { get; set; } 
     bool State { get; set; } 
     bool SetItemXml(XPathNavigator navigator); 
    } 

    [Serializable] 
    public class MyLink : IMyObject 
    { 
     public int Id { get; set; } 
     public string Url { get; set; } 
     public bool State { get; set; } 
     private XPathNavigator _xmlNavigator; 

     public bool SetItemXml(XPathNavigator navigator) 
     { 
      _xmlNavigator = navigator.Clone(); 
      Id = int.Parse(_xmlNavigator.SelectSingleNode("id").Value); 
      Url = _xmlNavigator.SelectSingleNode("url").Value; 

      return true; 
     } 
    } 

    [Serializable] 
    public class MyPicture : IMyObject 
    { 
     public int Id { get; set; } 
     public string Url { get; set; } 
     public bool State { get; set; } 
     private XPathNavigator _xmlNavigator; 

     public bool SetItemXml(XPathNavigator navigator) 
     { 
      _xmlNavigator = navigator.Clone(); 
      Id = int.Parse(_xmlNavigator.SelectSingleNode("id").Value); 
      Url = _xmlNavigator.SelectSingleNode("url").Value; 

      return true; 
     } 
    } 

    public partial class _Default : System.Web.UI.Page 
    { 
     public IDictionary<string, IDictionary<int, IMyObject>> CreateObjects() 
     { 
      IDictionary<string, IDictionary<int, IMyObject>> objects = new Dictionary<string, IDictionary<int, IMyObject>>(); 

      var reader = new XmlTextReader(new StringReader(@"<?xml version='1.0' encoding='utf-8'?><root><item><type>MyLink</type><id>1</id><url>http://www.google.com</url></item><item><type>MyLink</type><id>2</id><url>http://stackoverflow.com</url></item><item><type>MyPicture</type><id>3</id><url>http://static.adzerk.net/Advertisers/2565.png</url></item></root>")); 
      XPathNavigator navigator = new XPathDocument(reader).CreateNavigator(); 
      XPathNodeIterator nodes = navigator.Select("//root/item"); 

      while (nodes.MoveNext()) 
      { 
       string classType = nodes.Current.SelectSingleNode("type").Value; 
       int id = int.Parse(nodes.Current.SelectSingleNode("id").Value); 
       if (!objects.ContainsKey(classType) || !objects[classType].ContainsKey(id)) 
       { 
        IMyObject myObject = Activator.CreateInstance(Type.GetType(string.Concat("ObjectReference.", classType))) as IMyObject; 
        myObject.SetItemXml(nodes.Current); 

        if (!objects.ContainsKey(classType)) 
         objects.Add(classType, new Dictionary<int, IMyObject>() { { id, myObject } }); 
        else if (!objects[classType].ContainsKey(id)) 
         objects[classType].Add(id, myObject); 
       } 
      } 

      return objects; 
     } 

     protected void Page_Load(object sender, EventArgs e) 
     { 
      IDictionary<string, IDictionary<int, IMyObject>> ObjectList = new Dictionary<string, IDictionary<int, IMyObject>>(); 

      if (HttpContext.Current.Cache["ObjectCache"] != null) 
      { 
       ObjectList = (Dictionary<string, IDictionary<int, IMyObject>>)HttpContext.Current.Cache["ObjectCache"]; 
      } 
      else 
      { 
       ObjectList = CreateObjects(); 

       HttpContext.Current.Cache.Insert(
        "ObjectCache", 
        ObjectList, 
        null, 
        DateTime.Now.AddMinutes(2), 
        System.Web.Caching.Cache.NoSlidingExpiration); 
      } 

      foreach(var parent in ObjectList) 
      { 
       foreach(var child in ObjectList[parent.Key]) 
       { 
        if(false == child.Value.State) 
        { 
         //TODO... Note here 
         child.Value.State = true; 
        } 
       } 
      } 
     } 
    } 
} 

Répondre