Vogen icon indicating copy to clipboard operation
Vogen copied to clipboard

More (binary) serializers support: protobuf, messagepack

Open justmara opened this issue 2 years ago • 6 comments

Describe the feature

These serializers (protobuf-net, messagepack-csharp) are fast binary ones, already stated as industry standards (like, protobuf is used in gRPC) and they require a bit special handling: members decoration with attributes, accessible constructor. These two are pretty hard to be added to models, generated with current version of Vogen. Messagepack can make use of [SerializationConstructor] attribute, for example.

PS: Or is it possible to deal with these using current Vogen version and I (maybe) missed some guide for it?

justmara avatar Dec 12 '22 06:12 justmara

Hi - thanks for the feature suggestion. I think it'd make an excellent suggestion!

I'm not very familiar with this stuff though, so I'll do a bit of research and add them - hopefully within a week or so.

Thanks again!

SteveDunn avatar Dec 12 '22 07:12 SteveDunn

I've dug a bit into it and looks like MessagePack formatter is very simple:

public class SkuIdMessagePackFormatter : IMessagePackFormatter<SkuId>
{
    public void Serialize(ref MessagePackWriter writer, SkuId value, MessagePackSerializerOptions options) => writer.WriteInt64(value.Value);
    
    public SkuId Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
    {
        if (reader.TryReadNil()) return SkuId.Unspecified; // this must be some more general for sure :)

        options.Security.DepthStep(ref reader);

        var value = reader.ReadInt64();

        reader.Depth--;
        return SkuId.From(value);
    }
}

But the protobuf one seems to be pointless overall - it will require adding this type to proto, protobuf-gen wont recognize that special type anyway... Looks like this conversion must be done manually/on mapping stage and does not require any special handling, so can be avoided :)

justmara avatar Dec 12 '22 12:12 justmara

Also there is very interesting MemoryPack that I wanted to try out, but it uses its own roslyn generator and it fails even building project where it and vogen are added at the same time :(

justmara avatar Dec 12 '22 13:12 justmara

Interesting! Many thanks, I'll take a look at those.

SteveDunn avatar Dec 13 '22 21:12 SteveDunn

protobuf-net can be used with Vogen types very easily if adding dependency to protobuf-net is OK, but this information is not easy to find imho. I guess it's possible to set surrogate for every required type at the runtime too, but this seems more convenient for my use case.

[ValueObject(typeof(string))]
[ProtoContract(Surrogate = typeof(string))]
public partial class BoxId {
//...
}

BoxId type now will be serialized as a string in all messages/grpc calls. If one is generating .proto files for other applications from C# code, proto files will include Surrogate type as the type. @SteveDunn maybe this information should be included in readme?

DomasM avatar Oct 24 '23 08:10 DomasM

protobuf-net can be used with Vogen types very easily if adding dependency to protobuf-net is OK, but this information is not easy to find imho. I guess it's possible to set surrogate for every required type at the runtime too, but this seems more convenient for my use case.

[ValueObject(typeof(string))]
[ProtoContract(Surrogate = typeof(string))]
public partial class BoxId {
//...
}

BoxId type now will be serialized as a string in all messages/grpc calls. If one is generating .proto files for other applications from C# code, proto files will include Surrogate type as the type. @SteveDunn maybe this information should be included in readme?

Many thanks for the feedback @DomasM ! I'll certainly add that to the readme!

SteveDunn avatar Oct 24 '23 20:10 SteveDunn