2010-11-22 15 views
1

私はDictionary変数を持っています。プログラムはXMLファイルを読み込み、Dictionary変数に格納されたオブジェクトをパフォーマンスのためにタイプ別にインスタンス化します。 Dictionary変数を再利用するためにmemcacheに保存したいと思いますが、Dictionary変数とインスタンス化されたオブジェクトが参照型なので、インスタンス化されたオブジェクトを操作して値を変更すると、memcacheのキャッシュ値も変更されます。辞書変数をシリアライズ/デシリアライズする方法は?

コードは次のようになります。 クラスのディクショナリ変数およびXPathNavigator変数をシリアル化できません。シリアル化/デシリアライズする方法、または同様の効果を得る方法はありますか?ありがとう。

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; 
        } 
       } 
      } 
     } 
    } 
} 

答えて

関連する問題