Wrapping XMLSerializer
-
25-05-2021 - |
Question
I wish to put the XMLSerializer behind a 'facade' class of mine so that user wont have to supply type info to the constructor. But doing this has a problem. Consider this class:
Class XmlFormatter
Private Shared xs As XmlSerializer
Public Function Deserialize(ByVal serializationStream As Stream) As Object
Dim o As Object = Nothing
If Not xs Is Nothing Then
o = xs.Deserialize(serializationStream)
End If
Return o
End Function
Public Overloads Sub Serialize(ByVal serializationStream As Stream, ByVal graph As Object)
If xs Is Nothing Then
xs = New XmlSerializer(graph.GetType())
End If
xs.Serialize(serializationStream, graph)
End Sub
End Class
The problem is that the user of this class cannot use Deserialize without first using Serialize because the XMLSerializer instance is created in Serialize and it is shared. But using Deserialize without this instance will simply return Nothing. Can this problem be solved?
Solution
XmlSerializer does not include the type, because it is a design decision on XmlSerializer that the type is not important. The following are 100% compatible, for example:
namespace X {
public class A {
public string B;
}
}
namespace Y.Z {
[XmlRoot("A"), XmlType("A")]
public class C {
[XmlElement("B")]
public string D {get;set;}
}
}
This is IMO the most useful approach, and allows:
- simple use with generated/proxy types
- switching between POCO/DTO
- cross-platform and cross-architecture usage (for example consuming a "full .NET" service from WP7/SL/XNA
- simple versioning without a strict client/server tie
Basically, I'm of the opinion that the client absolutely should know what it is expecting, and that relying on the type is the wrong approach.