Reputation: 324
I am using protobuf-net with protobuf-net.grpc and am attempting to get it to work on Xmarin/Ios.
Currently I have attempted to create a pre-compiled serializer:
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");
When i reference this .dll and do new PDASerializers().Serialize(new UserInfo())
it works without issues.
I am however walking into a brick wall when attempting to go all in into awesomeness and use protobuf-net.grpc
.
The issue is that as soon as I call: channel.CreateGrpcService<ISomeInterface>
I get a reflection.emit error:
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.
I read at various places turning off "AutoCompile" could be a work around. This did solve me nog begin able to call Serialize directly - so it would seem I have no need for a pre-compiled serializer.
After some digging into the inner workings of protobuf I attempted to do this:
typeof(TypeModel).GetMethod("SetDefaultModel", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { new PDASerializers() })
But regretfully this also did not solve the issue.
Concretely my question is as follows;
Is it possible to either replace the default serializer to use the pre-compiled one in protobuf-net.grpc or is there some other way to turn off "AutoCompile" globally (so also for protobuf-net.grpc)?
Upvotes: 2
Views: 490
Reputation: 1062502
A second read on this reveals that you're actually looking for gRPC support. This is actually possible right now - you just need to provide a custom binder config:
var binderConfig = BinderConfiguration.Create(new List<MarshallerFactory> {
ProtoBufMarshallerFactory.Create(yourModelHere)
});
Now you can use that binderConfig
when creating clients (or registering servers, if you like), and: it should all work.
As for the pre-compile bit:
The answer here is complex. V3 is designed to facilitate this exact scenario - but the build time bits (aka "generators") is not yet complete (it is a C# vNext/preview feature that we've been waiting on specifically for this).
Additionally, V3 splits the core and reflection pieces in half, specifically to reduce the reference surface area when you aren't using those features.
For can it be done today: yes, but right now it is a little awkward, while the dust settles. If you have a modest sized example I'd be happy to work with you to get something working. To demonstrate that it can be done: https://protogen.marcgravell.com/decode does exactly this today, and can successfully run in the browser via Blazor with zero runtime emit - it has pre-compiled serializers for the FileDescriptorSet
etc that is uses when needed.
Upvotes: 1