One of the great features of this network library is the ability to send custom objects and at the same time easily incorporate compression, encryption etc. This is in part due to the features made available from serialisation libraries such as protobuf-net. Demonstrating this functionality is the primary goal of the AdvancedSend example included in the ExampleConsole project of the download bundle. The goal of this tutorial is to briefly discuss some of the methods available when using more complex custom objects. There are several different approaches to serialising and deserialising more complex objects so if this tutorial does not cover your scenario please leave a comment or post on our forum.

As a short recap, most custom objects can be sent using the following syntax:

If using the Protobuf serialiser the class CustomObject should be defined as follows:

Note: Notice the addition of [ProtoContract] and [ProtoMember(n)] attributes.

This works very well for objects which contain value types and / or collections (e.g. list, dictionary etc)  of primitive data types. You can also use members that are instances of custom classes (or collections of them) that have also been marked up for serialization in this way.  Things can get a little bit more interesting if you want to include types that have not been designed for serialization using protobuf-net. A good example of this is an Image object. Although you can still use these in your custom objects you need to provide some extra implementation to ensure they can be serialised and deserialised correctly.

Non-Primitive Data Types

The following object acts as a wrapper for an Image object, note the addition of two methods
Serialize()
and
Deserialize()
which respectively have the attributes
[ProtoBeforeSerialization]
and
[ProtoAfterDeserialization]
. Since it is not possible to serialise the Image object directly these methods convert it into its binary form, byte[], on serialisation and deserialisation and store the result privately.

This approach can be used to successful include any non-primitive types in your custom objects. If you found this tutorial helpful, have any feedback or questions please leave a comment or post on our forums.

Inherited Classes

It is also possible to use inheritance structures. We can reuse the CustomObject class originally defined above, we only need to add an additional attribute to inform protobuf-net of the child class and also allow access to the parameterless constructor by changing it from private to protected:

And the child class which uses CustomObject as a base:

If an instance of the class ‘CustomObjectExt’ is serialized it will also retain any data from the base class.

Streams

You can also send directly using streams, you just nee to wrap them in StreamSendWrapper (API Link) first.

For More Information

  • Please see the protobuf-net documentation for further examples of the features available for serialisation and deserialisation.