I'm currently having a hard time moving DTOs from one assembly and namespace to another assembly and namespace. This is because I am using binary serialization to send/receive data. In binary serialization the contract is basically the assembly name and type namespace + name. If you move a type to a different assembly you essentially break the contract.
Does protobuf-net behave in the same way? What is the foundation of the protobuf-net contract? Does probuf-net allow me to move a type from one assembly to another without breaking backwards compatibility? What about moving namespaces?
The short version of this is "yes, that will be fine - and to work just like that is one of the main reasons I wrote it in the first place".
In binary serialization the contract is basically the assembly name and type namespace + name.
That depends on how you define "binary serialization"; if you mean "serialization to something that happens to be binary, i.e. non-text", then that is unrelated. If you mean "type-based serialization", then: indeed - this is a major pain point.
Does protobuf-net behave in the same way?
No, it does not.
What is the foundation of the protobuf-net contract?
Types are not described at all; the caller supplies the type of the outermost member, and all other types are implied by the type's layout.
Members are identified solely via numeric keys; if those keys exist on both sides (and they don't necessarily need to : you can add / remove members), then they must be compatible. For example, these are compatible:
[ProtoContract]
public class Foo { // in namespace X
[ProtoMember(1)]
public int Id {get;set;}
[ProtoMember(2)]
public string Name {get;set;}
}
...
[ProtoContract]
public class User { // in namespace Y
[ProtoMember(2)]
public string UserName {get;set;}
}
If you serialize a Foo
and then deserialize it as a User
, the data from field 2 is pushed into UserName
(the data from field 1 is ignored by default, but can be stored if you need that). This, however, is not with Foo
:
[ProtoContract]
public class BadClass {
[ProtoMember(2)]
public double Quantity {get;set;}
}
(this will fail, as the wire-types for string
and double
are not remotely comparable)
Does probuf-net allow me to move a type from one assembly to another without breaking backwards compatibility? What about moving namespaces?
Yes to both. When you consider that you can be serializing in C# and deserializing in a Java or C++ model, it has to work this way.