Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XmlSerializer and factory-created elements

I am trying to serialize/deserialize objects that have factory-created members. For example, lets say there are a member of type Foo, which is instantiated using FooFactory.CreateFoo(int bar).

My current idea is to

1.create a custom XmlReader (for example, derive from XmlTextReader), and attach the factory to it

2.implement IXmlSerializable

3.in ReadXml(), I can the grab the factory from the reader.

Not sure if this is the most elegant way to do it, has anybody made similar attempts ?

like image 796
Oyvind Avatar asked Nov 21 '11 12:11

Oyvind


People also ask

What is XmlSerializer?

XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport. Deserialization re-creates the object in its original state from the XML output.

Why do we use XmlSerializer class?

XmlSerializer enables you to control how objects are encoded into XML. The XmlSerializer enables you to control how objects are encoded into XML, it has a number of constructors.

How does the XmlSerializer work C#?

The XmlSerializer creates C# (. cs) files and compiles them into . dll files in the directory named by the TEMP environment variable; serialization occurs with those DLLs. These serialization assemblies can be generated in advance and signed by using the SGen.exe tool.

Is XmlSerializer thread safe?

Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance.


1 Answers

XmlSerializer simply isn't set up for that. I would strongly suggest that if you want to use XmlSerializer, your best bet would be to map your data to a simpler DTO model first, and serialize that. When writing code back from the DTO to your model, add the factory creation there, in regular code. The DTO model should be simple; simple enough for XmlSerializer to be happy with it.

Yes, implementing IXmlSerializable is an option, however: that API is very hard to get 100% right (to handle all the various ways xml can appear to it). I find that API very hard, and I do a lot of serialization. I humbly submit that writing a few lines of code to map from your main model to a DTO model is a lot more robust (and a lot quicker) than trying to implement IXmlSerializable.

For example, you could have:

[XmlRoot("foo")]
public class FooDTO {
     [XmlAttribute("bar")]
     public int Bar {get;set;}

     public static implicit operator Foo(FooDTO value)
     {
         return value == null ? null : FooFactory.Create(value.Bar);
     }
     public static implicit operator FooDTO(Foo value)
     {
         return value == null ? null : new FooDTO { Bar = value.Bar; }
     }
}

then you can convert from Foo to FooDTO simply by:

Foo foo = ...
FooDTO dto = foo;
like image 118
Marc Gravell Avatar answered Sep 21 '22 16:09

Marc Gravell