Skip to content

Serialization Architecture

Dinesh Singh edited this page Jul 14, 2018 · 2 revisions

Serialization-Architecure

MessagePack for CLI consists of 3 components -- core, serializer, and serializer generater. A core library provides basic reader/writer for msgpack format(Packer and Unpacker) and an object model to support msgpack type system(MessagePackObject). In fact, core library only depends on BCL(mscorlib), so you can build own subset which only contains core library. In past, Silverlight drop was actually divided into core library and serializer library. Serializers are effectively mappers between msgpack stream and CLI objects. Serializers are categorized in 4 kinds -- primitive serializers, encoding serializers, collection serializers, and composite serializers. Primitive serializers are built in 'Adapter' between core library API and Serializer interface. They are generic MessagePackSerializer<T> implementation for primitive types. They only delegate serializer API invocations to corresponding Packer and Unpacker implementations. Note that serializer generators do not use them to gain performance, they emit direct Packer or Unpacker invocation instead, so primitive serializers effectively provide 'perfectness' of serializer sets and a bit convinience for custom serializer authors. Encoding serializers encode objects to MessagePack stream with their own way. They mostly exist for non-composite objects which have a single primitive underlying value like DateTime, Uri, and non-SZ Array. Primitive serializers and encoding serializers are all built-in hand made serializers (as you see, T4 template is used to generate them when possible), and they really are replaceable via SerializationContext.Serializers, but it should not add any values, so it is not recommended at all. Collection serializers just iterate collections and emit items to the stream as array or map (for both of generic and non-generic IDictionary). Of course, they can deserialize collections as they first instanciate the collection with their initial capacity if available in the constructor (the argument will be size of deserializing array or map), then feed items via UnpackTo method. Collection serializers are naturally universal, so their instructions are not generated except instanciation of the collection itself. Last one, composite serializers are main dish of this discussion. They maps object members to array or map items of MessagePack stream. For performance reasons, they are generated by serializer generators except reflection flavor configuration. Serializer generators are most complex components of the library. They analyze the type to be serialized, and then emit serializer CODE with some extra features like nil implication and error handling using appropriate technology. What does the term "appropriate technology" mean? Unfortunately, there are no portable way to implement dynamic code generation in the world as long as this article was written. Some environment only supported DynamicMethod (namely Silverlight 4, but we don't support it now), AssemblyBuilder(.NET 3.5), Expression Trees (Silverlight 5, WinRT), or not at all (Unity or Xamarin for iOS, so reflection based implementations will be used).