stimms
stimms

Reputation: 44046

Generic serializer with ProtoBuf.net

I'm attempting to write a generic serializer using protobuf.net v2. However I'm running into some issues which make me wonder if perhaps what I'm doing is impossible. The objects to be serialized are of an indeterminate type to which I don't have access so I'm attempting to walk the object and add its properties to the type model.

        var model = TypeModel.Create();
        List<string> propertiesToSerialize = new List<string>();
        foreach (var property in typeToSerialize.GetProperties())
        {
            propertiesToSerialize.Add(property.Name);
        }
        model.AutoAddMissingTypes = true;
        model.Add(typeToSerialize, true).Add(propertiesToSerialize.ToArray());

For simple objects which contain only primitives this seems to work just fine. However when working with an object which contains, say, a Dictionary<string,object> I encounter an error telling me that no serializer is registered for Object.

I did look at serializing a Dictionary<string,object> in ProtoBuf-net fails but it seems the suggested solution requires some knowledge and access to the object being serialized.

Any suggestions on how I might proceed?

Upvotes: 2

Views: 1539

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062502

protobuf-net does not set out to be able to serialize every scenario (especially those dominated by object), in exactly the same way that XmlSerializer and DataContractSerializer have scenarios which they can't model. In particular, the total lack of metadata in the protobuf format (part of why it is very efficient) means that it is only intended to be consumed by code that knows the structure of the data in advance - which is not possible if too much is object.

That said, there is some support via DynamicType=true, but that would not currently be enabled for the dictionary scenario you mention.

In most cases, though, it isn't really the case that the data can be anything; more typically there are a finite number of expected data types. When that is the case, the object problem can be addressed in a cleaner way using a slightly different model (specifically, a non-generic base-type, a generic sub-type, and a few "include" options). As with most serialization, there are scenarios were it may be desirable to have a separate "DTO" model, that looks closer to the serialization output than to your domain model.

A final note: the GetProperties()/Add() approach is not robust, as GetProperties() does not guarantee any particular order to the members; with protobuf-net in the way you show, order is important, as this helps determine the keys to use. Even if the order was fixed (sorting alphabetically, for example), note that adding a member could be a breaking change.

Upvotes: 2

Related Questions