2016-12-30 12 views
0

В настоящее время я работаю с буферами протоколов (версия 3 C#). Я отправляю сообщения туда и обратно в разные службы. и в настоящее время пытается сохранить некоторые данные, хранящиеся в определенных сообщениях в базе данных (может быть любого типа на самом деле).Буферы протокола сериализации/десериализации

Проблема в том, что байт [] создается как тип байтовой строки и Список < T> создается как RepeatedField < Т>. Теперь у меня есть проблема с тем, что мне не удалось выполнить сериализацию или десериализацию на 100% успешно.

Основные типы работают как шарм, но протокольные буферы могут быть сложными.

Я попытался AutoMapper и создал карты, которые сделали возможное байтовую строку сериализации/десериализации, но RepeatedField трудно, так как он предназначен только для чтения и имеет отдельный сеттер и не устанавливаемые в конструкторе.

Я не могу заставить AutoMapper правильно отображать его, я не удивлюсь, если на пути возникнут проблемы, и было интересно, есть ли более простые способы сохранять сообщения в базе данных?

Я прочитал более старые версии protobuf, где (если не ошибаюсь) были так называемые сборщики, что вы могли получить доступ к свойствам для каждого сообщения, которое было изменчивым, и упростило бы сериализацию/десериализацию. Или есть более очевидный способ получить доступ к данным и сохранить их в базе данных, которую я просто не вижу?

Я понимаю причину, по которой сообщения неизменяемы, но действительно ли нет прямого пути сохранения контактирующих данных в базу данных? Почувствует себя важной особенностью.

PS: Я знаю, что существует решение protobuf-net, которое обрабатывает сериализацию/десериализацию, но поддерживает только protobuf v.2, и я сильно зависим от функций v.3, таких как Any.

ответ

1

У меня есть AutoMapper 6.1.1 для сопоставления с protobufs 3 RepeatedField <>. Я уверен, что отражение может быть улучшено, но конфигурация AutoMapper:

void Configure(IMapperConfigurationExpression cfg) 
{ 
    cfg.CreateMap<ProtoThings, HasListOfThings>().ReverseMap(); 

    bool IsToRepeatedField(PropertyMap pm) 
    { 
     if (pm.DestinationPropertyType.IsConstructedGenericType) 
     { 
      var destGenericBase = pm.DestinationPropertyType.GetGenericTypeDefinition(); 
      return destGenericBase == typeof(RepeatedField<>); 
     } 
     return false; 
    } 
    cfg.ForAllPropertyMaps(IsToRepeatedField, (propertyMap, opts) => opts.UseDestinationValue()); 
} 
+0

Отлично! было долгое время с тех пор, как я баловался этим проектом, но ради любопытства я обязательно это проверю. Моим решением было загрузить исходный код клиента protoc и сменить генератор кода, чтобы все повторяющиеся поля имели публичные сеттеры, если я не ошибаюсь. Предпочитаете свое решение, если оно работает. Я дам вам знать, спасибо. – user4319995

+0

Этот раствор работал для меня с proto3 и AutoMapper 6.2.2 –