| File: MS\Internal\Annotations\Serializer.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // // Description: // Serializer performs the boot-strapping to call the public implementations // of IXmlSerializable for the Annotation object model. This would normally // be done by XmlSerializer but its slow and causes an assembly to be generated // at runtime. API-wise third-parties can still use XmlSerializer but we // choose not to for our purposes. // using System.Reflection; using System.Xml; using System.Xml.Serialization; namespace MS.Internal.Annotations { /// <summary> /// Serializer class for Annotation object model. All entities /// in the object model implement IXmlSerializable (or are /// contained and serialized by an entity that does). This class /// does the simple boot-strapping for serializing/deserializing /// of the object model. This lets us get by without paying the /// cost of XmlSerializer (which generates a run-time assembly). /// </summary> internal class Serializer { /// <summary> /// Creates an instance of the serializer for the specified type. /// We use the type to get the default constructor and the type's /// element name and namespace. This constructor expects the /// type to be attributed with XmlRootAttribute (as all serializable /// classes in the object model are). /// </summary> /// <param name="type">the type to be serialized by this instance</param> public Serializer(Type type) { Invariant.Assert(type != null); // Find the XmlRootAttribute for the type object[] attributes = type.GetCustomAttributes(false); foreach (object obj in attributes) { _attribute = obj as XmlRootAttribute; if (_attribute != null) break; } Invariant.Assert(_attribute != null, "Internal Serializer used for a type with no XmlRootAttribute."); // Get the default constructor for the type _ctor = type.GetConstructor(Array.Empty<Type>()); } /// <summary> /// Serializes the object to the specified XmlWriter. /// </summary> /// <param name="writer">writer to serialize to</param> /// <param name="obj">object to serialize</param> public void Serialize(XmlWriter writer, object obj) { Invariant.Assert(writer != null && obj != null); IXmlSerializable serializable = obj as IXmlSerializable; Invariant.Assert(serializable != null, "Internal Serializer used for a type that isn't IXmlSerializable."); writer.WriteStartElement(_attribute.ElementName, _attribute.Namespace); serializable.WriteXml(writer); writer.WriteEndElement(); } /// <summary> /// Deserializes the next object from the reader. The /// reader is expected to be positioned on a node that /// can be deserialized into the type this serializer /// was instantiated for. /// </summary> /// <param name="reader">reader to deserialize from</param> /// <returns>an instance of the type this serializer was instanted /// for with values retrieved from the reader</returns> public object Deserialize(XmlReader reader) { Invariant.Assert(reader != null); IXmlSerializable serializable = (IXmlSerializable)_ctor.Invoke(Array.Empty<object>()); // If this is a brand-new stream we need to jump into it if (reader.ReadState == ReadState.Initial) { reader.Read(); } serializable.ReadXml(reader); return serializable; } // XmlRootAttribute - specifies the ElementName and Namespace for // the node to read/write private XmlRootAttribute _attribute; // Constructor used to create instances when deserializing private ConstructorInfo _ctor; } }