views:

116

answers:

5

I've got an interface that two classes implement at the moment. The data for these classes is read in from an xml file.

e.g.

[Serializable]
public interface IMyInterface { }

[Serializable]
public class MyClass1 : IMyInterface { }

[Serializable]
public class MyClass2 : IMyInterface { }

I want to infer the type from the Xml, is there a way of doing that?

So for example my xml looks like this:

 <meta type="MyClass1">
   <!--- Some meta data -->
 </meta>

I want to be able to directly serialize from xml into objects. Currently I'm manually processing the xml.

Edit: To clarify, I know how to serialize out but I can't serialize back in without knowing which type it is first. Should I read the type attribute and then serialize based on that?

A: 

I don't know if this can help, but here it goes...

What if you put a public property on the classes that returns the typename

[XmlAttribute]
public string Type {
    get { return GetType().Name; }
}
Jhonny D. Cano -Leftware-
A: 

Try adding the [Serializable] attribute to each class. This requires that each have a parameter-less constructor.

Then you can use the XmlSerializer to serialize your object into xml.

XmlSerializer serializer = new XmlSerializer(myClass.GetType());
serializer.Serialize(writer, result);

Then you can add attributes to properties if you need to

[XmlElement(ElementName="MyClassIsAwesomeName", DataType="string")]
public string Name { get; set; }

or make sure a property isn't included by using the [XmlIgnore] attribute

hunter
Thanks, sorry I should have been clearer. I want to serialize from xml without knowing the concrete type first..
Rob Stevenson-Leggett
+1  A: 

If you are using XmlSerializer, you can add the XmlIncludeAttribute to specify the derived classes that can be deserialized. But the thing is that you have to add it to the base class:

[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
    public abstract bool Property { get; set; }
}

public class DerivedClass : BaseClass
{
    public override bool Property { get; set; }
}

Other way would be to implement IXmlSerializable for the member that can be derived, and then have a Factory for derived classes based on an attribute (or is that what you are doing right now?)

Groo
That is what I'm doing now, I'll consider switching to a base class.. It might make sense anyway. Thanks.
Rob Stevenson-Leggett
+1  A: 

The XML Serializer is not meant for situations like this. It's meant for serializing objects that can be mapped in to XML described by an XML Schema.

On the other hand, runtime serialization includes a SOAP Formatter that can serialize objects, including details of their .NET types. So can the NetDataContractSerializer in WCF.

John Saunders
+1  A: 

Hey,

If I understand your query correctly....

Have a property in your interface, say

[Serializable] public interface IMyInterface { YourClassDifferentiatorEnum ObjectDifferentiator { get; set; } }

And let each class set this value with distinct enum value. Serialize these concrete class into xml.

when you want to deserialize (xml back to concrete object), then deserialise it to IMyInterface. check for the object differentiator.. and cast accordingly..

Thanks 123Developer

123Developer