The default behaviour for XMLSerializer is hitting a loop because as part of trying to work out how to serialse a BindingNode, it then tries to figure out how to serialise an IEnumerable<BindingNode>, and to do that it tries to figure out how to serialise a BindingNode.
There's nothing to say that you can't have BindingNode implement IEnumerable<BindingNode>, just that the default XMLSerializer behaviour isn't going to work.
If you implement IXmlSerializable, then you control the serialisation yourself. Since you already know the structure of a BindingNode, you don't have to work that out at runtime! If you've a guarantee of an acyclic graph (it's impossible to have a BindingNode that is an ancestor of itself), then this is trivial:
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("BindingNode");
//More stuff here.
foreach(BindingNode contained in this)
contained.WriteXml(writer);
writer.WriteEndElement();
}
If the graph can by cyclic, it's just slightly more complicated in that you need to be able to instead of writing an element with all the details included, that you write an element that references a node already serialised to the stream, as otherwise the actual writing goes on forever and if you're lucky you hit a different cause of a stack overflow pretty soon (if you're unlucky the program merrily writes gigs and gigs of a file to disk first, and then hits it).
public int SomeSortOfUniqueID
{
get
{
//guess what this property has to do!
}
}
public void WriteXml(XmlWriter writer)
{
WriteXml(writer, new HashSet<BindingNode>());
}
private void WriteXml(XmlWriter writer, HashSet<BindingNode> alreadyWritten)
{
if(alreadyWritten.Add(this))
{
writer.WriteStartElement("BindingNode");
writer.WriteAttributeString("uniqueID", SomeSortOfUniqueID.ToString());
//More stuff here.
foreach(BindingNode contained in this)
contained.WriteXml(writer, alreadyWritten);
writer.WriteEndElement();
}
else
{
//we need to reference a node already mentioned in the document.
writer.WriteStartElement("BindingNode");
writer.WriteAttributeString("refID", SomeSortOfUniqueID.ToString());
writer.WriteEndElement();
}
}
Of course, you'll also have to implement ReadXml() to parse the XML back again.