According to this post (from March), protobuf v2 allows us to resolve types from a stream. Since v2 is now in beta 5, I think this feature has already been implemented, so I was wondering how to use this new feature. I haven't been able to find any documentation on it, so some help would be greatly appreciated !
Type meta
The serialization is fine, but I don’t know (and cannot know) all of my types up front. How can I do this?
Well, protobuf is a contract based format; if you don’t know the types, it will struggle – as will any contract based serializer…
Yes, I get that; now: how do I do it?
Now, I’ve held off putting any meta in the stream for various reasons:
it steps far outside the core protobuf spec it flashes the warning signs of BinaryFormatter, my nemesis But, so many people seem to want this that I think I have to buckle; but on my terms! So in v2, I’m adding the ability to indicate that (on a per-member basis) objects should resolve their type information from the stream. By default, by embedding the assembly-qualified-name, but providing an abstraction layer over that allowing you to provide your own string<===>Type map (and thus avoiding the knots in by stomach caused by too much type dependency).
The trick here is to use the DynamicType = true option on a member to your object - as an over-simplified example:
[ProtoMember(12, DynamicType = true)]
public object CouldBeAnything {get;set;}
Re the "string<===>Type map", that is the DynamicTypeFormatting event on TypeModel. If you are using the Serializer.* methods, that is a shortcut (mainly for preserving the v1 API) to the RuntimeTypeModel.Default serializer instance.
(as a side-note, in writing this I did notice an edge-case that I need to go and fix in the code)
Note: another approach here, rather than using DynamicType, is to simply configure the model at runtime, for example:
var knownTypes = GetMyKnownTypesAtRuntimeWithUniqueIdentifiers();
var metaType = typeModel[typeof(MyBaseClass)];
foreach(var knownType in knownTypes)
{
metaType.AddSubType(knownType.UniqueIdentifier, knownType.Type);
}
IMO this latter is my preferred option, and will generally be more efficient. Note that it is necessary for the unique-identifiers to be fixed/repeatable, as that is part of the wire format (don't just use the index of the order you find them).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With