views:

394

answers:

2

Trying to get my mind around google protobuf. I found some implementation of protobuf in C# but they seems to lack one feature: the ability to generate .proto files automatically from an existing C# class decorated with attributes.

The reason I want to do it this way instead of going from auto-generated C# classes from .proto file is because I already have the C# classes defined in my project and I don't want to duplicate them just to satisfy ProtoBuf.

Does anyone have encountered such a scenario?


Update

Is this possible to just decorate a C# class and not use a .proto file to use protobuf?

+2  A: 

Before Skeet Marc runs in here and gets massive ups, let me point out protobuf.net.

Will
Actually, that would be me ;-p
Marc Gravell
Yeah, I looked at the project but can't seem to find documentation about how to generate .proto files from a decorated C# class. Or is it needed to have a .proto file to use protobuf at all?
Stecy
Well, I only remember Skeet talking about it....
Will
Oh, Jon has a pb implementation; but a different one; dotnet-protobufs: http://github.com/jskeet/dotnet-protobufs/tree/master
Marc Gravell
And for the record, it wouldn't be a "fit" for this question (else I would have happily recommended it) - as it uses the codegen approach exclusively (exactly what the OP *doesn't* want).
Marc Gravell
+3  A: 

Good news; what you have described (having existing C# classes) is the expected use-case of protobuf-net. All the .proto stuff ("protogen", the VS add-in, etc) were all added as afterthoughts. The core of protobuf-net doesn't know about them or care about them.

protocol buffers defines a DSL (.proto, as you mention) that is shared between implementations, and is (sometimes) used for code generation. When I first wrote protobuf-net, the code-generation aspect wasn't my biggest concern - simply that .NET developers are generally guilty (myself included) of "implementation first" rather than "contract first".

As a consequence, protobuf-net doesn't need .proto files to work; an attributed class is sufficient to unambiguously serialize/deserialize. Just use Serializer.Serialize , .Merge and .Deserialize (etc).

That said; it does include some very under-developed and experimental support for this:

string proto = Serializer.GetProto<YourType>();

This is far from complete, but may work for simple types. If you have some specific cases where it fails, then let me know (add a comment or log an issue). However; most of the time, people interested in .proto would write the .proto first and work from there.

Examples of working decorated types are shown on the project home page; it is entirely up to you whether you use WCF attributes, xml attributes or protobuf-net attributes (although the latter provide more control over some specific serialization points, such as inheritance and numeric layouts).

Marc Gravell
Great, this would fit my requirements then. However, one more thing, does Protobuf-Net implements the whole specification of Protobuf?
Stecy
Pretty-much; the wire-format spec isn't vast, to be honest. Are you looking to interop with a separate .proto implementation? It should work fine, but if you *have* a .proto (for the other end), I'd recommend generating a DTO (from the .proto) and shim to that from your types. It also gets creative, allowing protobuf-net to support inheritance (which is **not** part of the core .proto spec), but done in a way that still allows full interop with other clients.
Marc Gravell
I am not looking to interop with another implementation. I will use protobuf-net as an efficient mechanism for serializing/deserializing a whole hierarchy of objects between two applications.
Stecy
One other thing, is it possible to have a serialization of a property defined as an IList but the actual object is a List?
Stecy
That should be fine as long as your class creates the concrete list. If it doesn't work, let me know (I'll try to remember to test it on the train tomorrow).
Marc Gravell
I've just checked, and a pre-initialized `IList<T>` works fine; I've also tweaked it to use `List<T>` if the list *isn't* pre-initialized.
Marc Gravell
You're right! I was not initializing the concrete list in my private constructor. I like ProtoBuf-Net more and more... :)
Stecy