4

What NuGet package should I use between protobuf-net and google.protobuf for a new .net core app?

  • It is for "Code first", not contract first.
  • It is actually only for C# but would be great if more languages could easily read the format but not a must. I would favor performance over portability for binary serialization. I will also use XML or Json for portability (which for my opinion is better suited for portability although a lot slower).
Eric Ouellet
  • 10,996
  • 11
  • 84
  • 119
  • the one that better fits your needs... otherwise, this question is completely opinion-based and therefore off-topic. by the way: your addendum sounds like you'ry trying to advertise for protobuf. – Franz Gleichmann Oct 14 '20 at 18:54
  • Thanks for your comment. But my primary question is which one between 2 Nuget package? I just added another one about performance for additional info. I do not agree with you that performance is opinion based at all.I do not advertise for protobuf at all. But I already use it and found that it was pretty fine, a lot better than many other choices. – Eric Ouellet Oct 14 '20 at 18:56
  • yes - your question is which one, i got that. but unless _you_ know what requirements you have and which one bette suits them - it is _completely_ up to opinion. my advise: just _try_ and compare them. (additionally: this could be seen as off-topic again since you want a _recommendation_ which of the (two) libraries you should use.) – Franz Gleichmann Oct 14 '20 at 19:00
  • yes, i have no idea about the answer (except that it's [here](https://stackoverflow.com/questions/48889817/google-protobuf-vs-protobuf-net?noredirect=1&lq=1) - have you _tried_ a search engine? ;)). but that's not why i downvoted. i downvoted because your question does _not_ show any effort and your question _is_ very subjective and opinion-based. if you care about performance, you _could_ just benchmark the two solutions (or search for existing benchmarks). if you have any architectural constraints, _you_ know best about them. this question, as it is, is just not a good question for SO. – Franz Gleichmann Oct 14 '20 at 19:11
  • The answer you gave me does not answer the question. The performance is not about the 2 implementations, it was about protobuf and the competition for which, since it was out a long time ago, should have some new competitors. My question is not related about my own constraint, it is totally objective and about general use cases. And yes, I always try to find my answers before asking. But I respect your opinion and really appreciate you took the time to explain me. – Eric Ouellet Oct 14 '20 at 19:18
  • 2
    Ok, if I may chime in: I *wrote* ones of those implementations, and I would say that *based on the text in the question*, there is no possible objective answer here. The only answer I could give is "it depends". – Marc Gravell Oct 14 '20 at 19:36
  • @MarcGravell Depends on what? Will I get something that could prevent me from serializing? Why so many implementation ? You only wrote one? Not all? There is also a *.Core one but they all supports .net core 3.1 – Eric Ouellet Oct 14 '20 at 19:40
  • @Eric if you mean protobuf-net.Core, that is a *component* - part of the same tooling. As for "on what" - well, "code first or contract first?" would be my first question. Also, "do you want idiomatic .NET, that happens to be protobuf, or do you want idiomatic protobuf that happens to be .NET?". Also perhaps "would it be useful to work natively in VB/F#/etc?". I could probably think of others, given time – Marc Gravell Oct 14 '20 at 19:46
  • @MarcGravell, I updated my question in order to try to be more explicit about my needs. I hope I provided enough information. I wonder how other peoples choose which package to use? – Eric Ouellet Oct 14 '20 at 19:57
  • @EricOuellet personally, i _research_ the differences. then compare then with my requirements. then chose the better. if there is none that's bette,r i pick the one that's more frequently updated and has the larger userbase, since it has better chances for support in the future. if they're similar in that regard, i flip a coin. – Franz Gleichmann Oct 14 '20 at 20:05
  • @FranzGleichmann, I never flip a coin when I code. There is always a reason why I choose something over another. I prefer ask instead of taking time to make tests that would takes long time and could bring me to the wrong choice anyway. I will keep your suggestions for making my choice if I really have no satisfying answer. Thanks. – Eric Ouellet Oct 14 '20 at 20:16
  • @EricOuellet the point of flipping the coin: if two options are virtually _equal_ in every point that matters - it makes no difference. see also: fredkin's paradox. – Franz Gleichmann Oct 14 '20 at 20:20
  • @MarcGravell, Do you think I'm alone with that question? The exact same interrogation? – Eric Ouellet Oct 14 '20 at 20:23
  • Reopening because *with the edit* I believe it becomes objectively answerable. – Marc Gravell Oct 15 '20 at 06:11

1 Answers1

10

With the edit, this becomes more answerable; first let's consider the options shown here, plus the Google implementation, in the context of the constraints in the question:

  1. Google.Protobuf - the reference implementation
  • + solid, dependable, well-maintained
  • - fundamentally "contract first" (unmanaged parser/generator), proto3 only
  1. protobuf-csharp-port
  • - strictly legacy, this effectively became Google.Protobuf; do not use
  1. SilentOrbit/protobuf
  • - fundamentally "contract first" (managed parser/generator)
  • (honestly, I don't know a lot about this one, so I'm not going to comment much for or against)
  1. protobuf-net
  • + "code first" or "contract first" (optional managed parser/generator)
  • + "code first" is usable to any .NET language; .proto schemas can be generated from code for use with any other platform/language (marked + because this is a non-essential nice to have, according to the question)
  • + reasonably well maintained (it isn't my day job, but I try!)

So; given that the question says:

It is for "Code first", not contract first.

It seems to become a very simple selection process, with protobuf-net being the only horse in that race. In terms of .NET Core: protobuf-net is fully up to date with .NET Core, including being optimized for the span APIs and looking ahead to .NET 5 / C# 9 features.

As a side note: if you're starting green-field, I would recommend using the v3 versions of protobuf-net and using the highest currently defined CompatibilityLevel

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks a lot Mark for re-opening this question and for the great answer. In fact, I'm very happy to have your direct answer and was hoping for it. Thanks also for adding information about Compatibility Level. The ModuleAttribute is new to me. Do I have to include it in each and every file where a class has "ProtoContract" attribute. Is there a way to tell the serialializer to use 300 directly by default? – Eric Ouellet Oct 15 '20 at 13:58
  • 1
    @Eric that's exactly what `[module:CompatibilityLevel(...)]` or `[assembly:CompatibilityLevel(...)]` do - they say "anything in this module/assembly: uses X". I would recommend module (instead of assembly) - most times when people say "assembly" they actually mean "module" (just: most assemblies only have one module, hence the confusion). You can also attach it to specific classes with different levels by *not* using the assembly/module prefix – Marc Gravell Oct 15 '20 at 19:37
  • As far as I can tell `protobuf-net` does not support the newish JSON format. I understand that JSON contradicts the purpose of using protobuf, but it is a feature and can be useful. Or do I have it all wrong? – Dave New Jun 23 '21 at 16:20
  • 1
    @Dave sure, but it is also a ton of work, which nobody has done, so... – Marc Gravell Jun 23 '21 at 22:49
  • @MarcGravell I always considered it as a code smell when your base class needs to know about its child classes for it to be binary serialized as mentioned here https://github.com/protobuf-net/protobuf-net#inheritance. Am I wrong in that assumption? – James Poulose Feb 03 '22 at 06:49
  • @JamesPoulose I would say "yes, you're worrying unduly"; also, I would be very cautious of the term "binary serialized", as "binary" is used in different ways in different contexts; protobuf is a contract serializer where the payload protocol is not text; the reason I call this out is that "BinaryFormatter", for example, is *completely different*. People usually expect the LSP to apply, which means that we need to be able to express things purely from their base/root types, including during deserialization - which means during deserialization we need to recognize child types from their (1/2) – Marc Gravell Feb 03 '22 at 07:21
  • @JamesPoulose (2/2) base types; discovering a base type (during serialization) is simple, but discovering inherited types: not reliably possible, without help (the types could be in assemblies that haven't even been loaded yet!) - so we have some relevant technical factors to content with; storing the AQN is a terrible idea (that's a data leak, large, brittle (it can change), and a known attack vector), so: nobody does that (except BinaryFormatter); also: see `[XmlInclude]`, `[KnownType]`, etc; summary: this is a: reasonable, b: common, and c: not problematic *when talking about a DTO* – Marc Gravell Feb 03 '22 at 07:24