Можно ли установить сериализатор по умолчанию на предварительно скомпилированный в 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, или есть какой-то другой способ отключить "AutoCompile" глобально (так же и для protobuf-net.grpc)?
1 ответ
Второе прочтение этого раздела показывает, что вы действительно ищете поддержку gRPC. На самом деле это возможно прямо сейчас - вам просто нужно предоставить настраиваемую конфигурацию связующего:
var binderConfig = BinderConfiguration.Create(new List<MarshallerFactory> {
ProtoBufMarshallerFactory.Create(yourModelHere)
});
Теперь вы можете использовать это binderConfig
при создании клиентов (или регистрации серверов, если хотите) и: все должно работать.
Что касается бита предварительной компиляции:
Ответ здесь сложный. V3 разработан для облегчения этого точного сценария, но биты времени сборки (также известные как "генераторы") еще не завершены (это функция C# vNext/preview, которую мы ждали специально для этого).
Кроме того, V3 разделяет сердцевину и отражающие части пополам, в частности, чтобы уменьшить площадь эталонной поверхности, когда вы не используете эти функции.
Ибо можно ли это сделать сегодня: да, но сейчас немного неудобно, пока пыль не уляжется. Если у вас есть пример скромного размера, я буду счастлив работать с вами, чтобы что-то заработало. Чтобы продемонстрировать, что это можно сделать: https://protogen.marcgravell.com/decode делает именно это сегодня и может успешно работать в браузере через Blazor с нулевым испусканием времени выполнения - он имеет предварительно скомпилированные сериализаторы дляFileDescriptorSet
и т. д., которые используются при необходимости.