Thursday, January 22, 2004

XmlSerialization and Interface Based Programming

Check out the code below and see if you can see spot what is wrong with it:

public interface IChildObject {
  string Name {get;set;}
}

public interface IContainerObject {
  IChildObject Child {
get;set;}
  void Save(string fileName);
}

public class ChildObj : IChildObject  {
  private string m_name = "Fred";
 
public string Name
  {
    get { return m_name; }
    set { m_name = value; }
  }
}

public class ContainerObj : IContainerObject {
  private ChildObj m_child = new ChildObj();
  public void Save(string fileName)
 {
    XmlSerializer xs =
new XmlSerializer(typeof(ContainerObj));
    FileStream fs = File.OpenWrite(fileName);
    xs.Serialize(fs,
this);
  }

  public IChildObject Child
  {
    get { return m_child; }
    set { m_child = value as ChildObj; }
  }
}

This was one of those subtle little things that was confounding a customer new to .NET, but the not so descriptive exception made it a little easier to figure out once I saw it:

InvalidOperationException: There was an error reflecting the type ContainerObj.

The issue of course is that XmlSerialization uses reflection to figure out what to write out. It probes the type and gets all its public fields and properties and writes those out with serialize or reads them in with deserialize. Because the container object exposed its child property as an interface type instead of the implementation type, the reflection stopped there and choked and it can't XML Serialize this type.

If it is already using reflection, why couldn't it have been coded to use reflection a little harder and determine the underlying type for any interface properties? There are a lot of situations it would be good to expose the property as an interface instead of a concrete type, but if you do that, you can no longer benefit from the simple XML serialization mechanism. I hate to have to violate good interface-based design just to take advantage of XML Serialization, but it seems like that is the only choice here.

I realize we could use normal .NET serialization (binary or SOAP), but XmlSerialization was ideal for the task at hand.

Hopefully the changes they are making to XML Serialization for Indigo will make this scenario OK.

Am I missing anything obvious?





Comments are closed.



















Sign In
Copyright © 2006-2007 Brian Noyes. All rights reserved.
designed by NUKEATION STUDIOS