What is the difference between ProtoBuf.Serializer and ProtoBuf.Meta.TypeModel in protobuf-net?

Viewed 963

As I recently discovered we can serialize/deserialize in protobuf-net using two classes ProtoBuf.Serializer and ProtoBuf.Meta.TypeModel. For example, let's say we have a custom class that we want to serialize/deserialize:

[ProtoContract]
public class Person
{
    [ProtoMember(1)]
    public string Name { get; set; }
    [ProtoMember(2)]
    public int Age { get; set; }
}

We can do it in two ways:

1) Using TypeModel

TypeModel typeModel = RuntimeTypeModel.Default;
var person1 = new Person
{
    Name = "John",
    Age = 23
};

using (var stream = new MemoryStream())
{
    typeModel.Serialize(stream, person1);
    stream.Position = 0;
    var pesrson2 = typeModel.Deserialize(stream, null, typeof(Person));
}

2) Using Serializer (which is the chosen way in most of the tutorials I've seen)

var person1 = new Person
{
    Name = "John",
    Age = 23
};
using (var stream = new MemoryStream())
{
    Serializer.Serialize(stream, person1);
    stream.Position = 0;
    var pesrson2 = Serializer.Deserialize<Person>(stream);
}

What is the difference between these two approaches. How to choose between these two? And what is TypeModel and RuntimeTypeModel in the first place?

1 Answers

All of the Serializer.* methods are generally just convenience proxies to RuntimeTypeModel.Default.*. There are probably a few minor exceptions - those that don't touch a model at all (processing a "varint", for example)

Essentially, in the 1.* API, there was only one model. v2 added the ability to have concurrent/parallel models describing the same types, and a much richer runtime configuration system - all of this is encapsulated into TypeModel - with the usual implementation being RuntimeTypeModel. Note that you can also load assemblies that contain pre-baked TypeModel implementations, so not every TypeModel is a RuntimeTypeModel.

So; if you're using simple types with attributes : you're fine using Serializer.*. If you've had to do more advanced things with runtime configuration and multiple models - you'll need to keep track of your various TypeModel instances so you know which one to use.

Related