Можно ли установить сериализатор по умолчанию на предварительно скомпилированный в 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 и т. д., которые используются при необходимости.

Другие вопросы по тегам