title: Dynamic Object Serialization
body: <p>I tried to serialize a <code>DynamicObject</code> class with <code>BinaryFormatter</code>, but:</p>
  
  <ul>
  <li>Output file is too big, not exactly wire-friendly</li>
  <li>Circular References not handled (stuck while serializing)</li>
  </ul>
  
  <p>Since <em>serializing a <code>DynamicObject</code></em> means very little by itself, here's the class I tried to serialize:</p>
  
  <pre><code>[Serializable()]
  class Entity
      : DynamicObject, ISerializable
  {
  
      IDictionary&lt;string, object&gt; values = new Dictionary&lt;string, object&gt;();
  
      public Entity()
      {
  
      }
  
      protected Entity(SerializationInfo info, StreamingContext ctx)
      {
          string fieldName = string.Empty;
          object fieldValue = null;
  
          foreach (var field in info)
          {
              fieldName = field.Name;
              fieldValue = field.Value;
  
              if (string.IsNullOrWhiteSpace(fieldName))
                  continue;
  
              if (fieldValue == null)
                  continue;
  
              this.values.Add(fieldName, fieldValue);
          }
  
      }
  
      public override bool TryGetMember(GetMemberBinder binder, out object result)
      {
          this.values.TryGetValue(binder.Name, out result);
  
          return true;
      }
  
      public override bool TrySetMember(SetMemberBinder binder, object value)
      {
          this.values[binder.Name] = value;
  
          return true;
      }        
  
      void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
      {            
          foreach (var kvp in this.values)
          {
              info.AddValue(kvp.Key, kvp.Value);                 
          }
      }
  
  }
  </code></pre>
  
  <p>(I guess I could have used an ExpandoObject, but that's another story.)</p>
  
  <p>Here's a simple test program:</p>
  
  <pre><code>    static void Main(string[] args)
      {
          BinaryFormatter binFmt = new BinaryFormatter();
  
          dynamic obj = new Entity();
          dynamic subObj = new Entity();
          dynamic obj2 = null;
  
          obj.Value = 100;
          obj.Dictionary = new Dictionary&lt;string, int&gt;() { { "la la la", 1000 } };
  
          subObj.Value = 200;
          subObj.Name = "SubObject";
  
          obj.Child = subObj;
  
          using (var stream = new FileStream("test.txt", FileMode.OpenOrCreate))
          {
              binFmt.Serialize(stream, obj);                
          }
  
          using (var stream = new FileStream("test.txt", FileMode.Open))
          {
              try
              {
                  obj2 = binFmt.Deserialize(stream);                    
              }
              catch (Exception ex)
              {
                  Console.WriteLine(ex);
              }                
          }
  
          Console.ReadLine();
  
      }
  </code></pre>
  
  <p>Putting some breakpoints here and there helped me have a look at obj2 contents and it looks like the original data is correctly deserialized, though with the above shortcomings if you get imaginative and move data around.</p>
  
  <p>I had a look at Marc Gravell's protobuf-net, but I'm not really sure how to use it in such a context (I'm not even sure I picked up the right version from the repository, but hey).</p>
  
  <p>I know it's more code than words, but I don't think I can explain the scenario any better. Please do tell if there's something I can add to make this question clearer.</p>
  
  <p>Any help is much appreciated.</p>