050. Serializers

While Silverlight does come with built-in serialization, it unfortunately does not provide a binary serializer. Sterling uses binary serializes for speed and compactness of data on disk. Binary data takes significantly less space on disk than XML and JSON formats, even without compression. In order to serialize complex object graphs, Sterling relies on serializers. Serializers are special classes that handle taking data types and write them to output streams and read them from input streams.

Sterling comes with two built-in serializers. The base serializer supports all methods that are available with the built-in binary writer, and the extended serializer handles task for other common classes and value types. You may also extend Sterling by writing your own serializer. Sterling automatically walks object graphs and persists properties that are supported by the serializers. If you have a type that Sterling is not serializing correctly, or wish to take control over how the serialization takes place (for example, your type does not have a parameterless constructor andyou  need to create an instance of the type on your own) you can create a custom serializer. A custom serializer can support multiple types.

The Default Serializer

The default serializer supports all types that are part of the built-in binary writer. These include:

 float (single)
 int (Int32)
 long (Int64)
 short (Int16)

The Extended Serializer

The extended serializer supports additional types that are not natively part of the binary writer, but are often used in Silverlight programs. The extended support includes:


When Sterling serializes an object, it will serialize all public properties it recognizes. That means a struct or class that contains either other structs or classes, or one of the types listed above, will be automatically handled by Sterling. Only a type that has a value type not handled by the default and extended serializers will need a customer serializer created.

Understanding the Aggregate Serializer 

Sterling always works with exactly one serializer. Internally, Sterling has an additional serializer called the AggregateSerializer that simply chains multiple children serializers together. The default and extended serializers are registered with the aggregate serializer and this is what Sterling uses. When you define and register a custom serializer, it is added to the aggregate serializer.

Creating a Custom Serializer

All serializers derive from the BaseSerializer class. The class requires that you implement three methods: CanSerialize, Serialize, Deserialize. Each method helps Sterling understand what your custom serializer is capable of doing. 

The first method, CanSerialize, tells Sterling whether or not your class is capable of serializing a type. In this way, custom serializers can support multiple types. When trying to serialize a type, Sterling will first pass the type to the aggregate serializer, which in turn passes the type to all child serializers, until it finds a serializer that returns "true." If this happens, the aggregate serializer will remember the custom serializer and always call it when the type is serialized or deserialized.

The Serialize method is passed a type and a stream to write to. In this method, you would write the object however you wish to represent it to the stream. The Deserialize method passes a type and an input stream. From the type, you will read the stream and reconstruct the type to pass back to Sterling. 

This example shows a serializer that handles a custom value type called NutrientDataElement.

Custom Serializer

Registering and Using a Custom Serializer

Serializers should be registered with the engine before it is activated. This is because the aggregate serializer is passed to databases when databases are activated. Failing to register the serializer at the appropriate time would cause the database to lose a reference to the serializer. 

The following command is all that is needed to register your custom serializer before activating the engine: 


When Sterling encounters any type supported by the serializer, it will automatically pass the instance to your serializer for handling.
Jeremy Likness,
Sep 1, 2011, 6:37 AM