As a result, I thought I’d spend some time looking for another option. It occurred to me that in WPF, I might’ve used the XamlWriter for precisely this purpose: to serialize my objects out into text. As I thought about my options for serialization, taking assembly size into account, I found myself wondering if XAML was a good choice. After all, Silverlight has a reader (XamlReader) built into the runtime, so I wouldn’t have to build one myself. Perhaps that would save me the size I was looking for. Furthermore, in Silverlight 4, the XAML parser got a major overhaul that helped ensure more consistent support of the XAML language, so I felt confident that I could produce a flexible XAML serializer.
With that in mind, I started writing. At first, I was just hoping to build out some basic serialization into XAML – enough to suit my needs for what I was working on. But unfortunately, once I start trying to solve a problem, I can’t leave it half-complete! Just like that, I was hooked on the challenge of seeing how complete of a XAML serializer I could build (which helps explain my blogging absence for the last month ).
Honestly, I expected to find a large number of issues – limitations of Silverlight that would keep me from collecting enough information to serialize to XAML properly. The reality, however, was that I could actually get really close to full fidelity.
In the process, I learned a lot about XAML, Silverlight, and myself (a journey of self-discovery, so to speak ). In this post, I’ll share my results (happily included for your consumption and experimentation in my latest build of SLaB) as well as some of what I learned. As usual, I make no promises around support or correctness in all cases. This is sample code for your edification. That said, if you do find an issue, please let me know, and I’ll see if I can figure out what’s going on!
POCO, oh, POCO, wherefore art thou?
I started out just trying to serialize POCOs (Plain ol’ CLR Objects). On the surface, this is pretty straightforward – walk the object graph being serialized, writing objects and property values out using the XmlWriter. Simple, right? Well, there’s actually a lot going on here:
Walk the object graph using reflection
Decide whether properties are serializable (i.e. is the property read-only? If so, is it a collection type?)
Retrieve TypeConverters from both properties and property types (based on the TypeConverterAttribute)
Determine whether to set properties as attributes (<Foo Bar=”Baz” />) or elements (<Foo><Foo.Bar><Baz /></Foo.Bar></Foo>)
Retrieve and honor ContentPropertyAttributes (So that if “Bar” is the ContentProperty of Foo, the example above is serialized as <Foo><Baz /></Foo>)
Determine whether properties should/should not be serialized based on the “ShouldSerializeXXXXX” method and the DefaultValueAttribute
Discover attached properties and repeat all of the above
Manage xml namespace definitions (e.g. xmlns:foo=”clr-namespace:MyAssembly.Foo;assembly=MyAssembly”) and scope
Discover/respect XmlnsDefintion and XmlnsPrefix attributes
Understand serialization of built-in types (e.g. Uri, string, double, int, bool, enums etc.)
Serialize null values (using “{x:Null}”)
Serialize collections
Serialize dictionaries (and make use of “x:Key”)
Properly escape strings (e.g. “{Hello, world!}” needs to get serialized as “{}{Hello World!}”)
Properly handle string whitespace (turning on xml:space=”preserve” at the appropriate times)
Avoid cycles in the object graph (I simply ignore the property if it would cause a cycle – sorry, I’m not a miracle worker!)
Be performant!
Nothing to it, right? Phew, I’m tired just writing all those down! Who knew there was so much to that XAML stuff? (answer: Rob Relyea)
Read more: davidpoll.com