是否可以将默认序列化程序设置为 protobuf-net 中的预编译序列化程序?

Is it possible to set the default Serializer to a pre-compiled one in protobuf-net?

我正在将 protobuf-net 与 protobuf-net.grpc 一起使用,并试图让它在 Xmarin/Ios.

上运行

目前我试图创建一个预编译的序列化程序:

            RuntimeTypeModel runtimeTypeModel = RuntimeTypeModel.Create();
            runtimeTypeModel.AllowParseableTypes = true;
            runtimeTypeModel.AutoAddMissingTypes = true;
            runtimeTypeModel.AutoCompile = false;
            runtimeTypeModel.Add(typeof(UserInfo), true);
            Directory.SetCurrentDirectory(@"..\..\");
            runtimeTypeModel.Compile("PDASerializers", @"PDASerializers.dll");

当我引用此 .dll 并执行 new PDASerializers().Serialize(new UserInfo()) 时,它可以正常工作。

然而,当我试图全力以赴并使用 protobuf-net.grpc 时,我正在走进一堵砖墙。

问题是,一旦我调用:channel.CreateGrpcService<ISomeInterface>,我就会收到 reflection.emit 错误:

Operation is not supported on this platform.

  at System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly (System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.pns.cs:129 
  at ProtoBuf.Grpc.Internal.ProxyEmitter..cctor () [0x0001e] in /_/src/protobuf-net.Grpc/Internal/ProxyEmitter.cs:18 

nb.

我在很多地方读到关闭“AutoCompile”可能是一种变通方法。这确实解决了我的问题,开始能够直接调用 Serialize - 所以我似乎不需要预编译的序列化程序。

在深入了解 protobuf 的内部工作原理后,我尝试这样做:

typeof(TypeModel).GetMethod("SetDefaultModel", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { new PDASerializers() })

但遗憾的是这也没有解决问题。


具体我的问题如下;

是否可以替换默认序列化程序以使用 protobuf-net.grpc 中的预编译序列化程序,或者是否有其他方法可以全局关闭“自动编译”(对于 protobuf-net.grpc 也是如此)?

再读一遍表明您实际上是在寻找 gRPC 支持。现在这实际上是可能的——你只需要提供一个自定义活页夹配置:

var binderConfig = BinderConfiguration.Create(new List<MarshallerFactory> {
    ProtoBufMarshallerFactory.Create(yourModelHere)
});

现在您可以在创建客户端(或注册服务器,如果您愿意)时使用它 binderConfig,并且:它应该一切正常。


至于预编译位:

这里的答案很复杂。 V3 旨在 促进 这个确切的场景 - 但构建时间位(又名“生成器”)尚未完成(这是我们一直在使用的 C# vNext/preview 功能专门为此等待)。

此外,V3 将核心部分和反射部分一分为二,专门用于在不使用这些功能时减少参考表面积。

今天可以完成:是的,但是现在有点尴尬,待尘埃落定。如果您有一个中等规模的示例,我很乐意与您合作以取得一些成果。为了证明它 可以 完成:https://protogen.marcgravell.com/decode 今天正是这样做的,并且可以通过 Blazor 在浏览器中 运行 成功 运行 发出零 运行time - 它为 FileDescriptorSet 等预编译序列化程序,在需要时使用。