Custom Xml Serialization of Unknown Type

c#, xml-serialization

Solution

To create an instance from a string, use one of the overloads of Activator.CreateInstance. To just get a type with that name, use Type.GetType.

Problem

I'm attempting to deserialize a custom class via the XmlSerializer and having a few problems, in the fact that I don't know the type that I'm going to be deserializing (it's pluggable) and I'm having difficulty determining it. I found this post which looks similar but can't quite get it to work with my approach because I need to deserialize an interface which is XmlSerializable. What I've currently got is of the form. Note that I expect and need to be able to handle both class A and class B to be implemented via a plugin. So if I can avoid using the IXmlSerializable (which I don't think I can) then that would be great. The ReadXml for A is what I'm stuck on. However if there are other changes that I can make to improve the system then I'm happy to do so. ``` public class A : IXmlSerializable { public IB MyB { get; set;} public void ReadXml(System.Xml.XmlReader reader) { // deserialize other member attributes SeekElement(reader, "MyB"); string typeName = reader.GetAttribute("Type"); // Somehow need to the type based on the typename. From potentially //an external assembly. Is it possible to use the extra types passed //into an XMlSerializer Constructor??? Type bType = ??? // Somehow then need to deserialize B's Members // Deserialize X // Deserialize Y } public void WriteXml(System.Xml.XmlWriter writer) { // serialize other members as attributes writer.WriteStartElement("MyB"); writer.WriteAttributeString("Type", this.MyB.GetType().ToString()); this.MyB.WriteXml(writer); writer.WriteEndElement(); } private void SeekElement(XmlReader reader, string elementName) { ReaderToNextNode(reader); while (reader.Name != elementName) { ReaderToNextNode(reader); } } private void ReaderToNextNode(XmlReader reader) { reader.Read(); while (reader.NodeType == XmlNodeType.Whitespace) { reader.Read(); } } } public interface IB : IXmlSerializable { } public class B : IB { public void ReadXml(XmlReader reader) { this.X = Convert.ToDouble(reader.GetAttribute("x")); this.Y = Convert.ToDouble(reader.GetAttribute("y")); } public void WriteXml(XmlWriter writer) { writer.WriteAttributeString("x", this.X.ToString()); writer.WriteAttributeString("y", this.Y.ToString()); } } ``` NOTE : Updated as I realised B was supposed to use interface IB. Sorry for slightly wrong question.

Original source