Требуется ли аннотация DataMember (Order = n) для protobuf-net v2?

Простой эксперимент: я создал модель объекта из Northwind и обнаружил, что сгенерированные классы не работают для protobuf-net v2 без добавления свойства Order. Есть ли способ заставить генератор кода сущности добавить Order или есть способ заставить protobuf-net работать без Order?

я должен изменить

[DataMemberAttribute()]

to

[DataMemberAttribute(Order=1)] и т.д.

NorthwindEntities e = new NorthwindEntities();

using(var file = File.Create("customers.bin"))
{
    Serializer.Serialize(file, e.Customers);
}

person P a u l    schedule 17.11.2011    source источник


Ответы (2)


Что требуется, так это то, что у него есть способ преобразовать члены в числовые ключи. Это может принимать форму встроенных атрибутов — например, он допускает [DataContract]/[DataMember(Order=key)], [XmlType]/[XmlElement(Order=key)] или [ProtoContract]/[ProtoMember(key)].

Есть также варианты через [DataContract] для вывода контракта в алфавитном порядке, но это безопасно только в том случае, если тип вашего контракта не собирается меняться в будущем; для этого добавьте:

[ProtoContract(InferTagFromName = true)]

к типу (возможно, частично, см. ниже). Это относится непосредственно к сценарию, который вы представляете, где [DataMember] указывает на участников, но не имеет определенного Order. Лично я предпочитаю явные макеты для стабильности.

Другой вариант даже не нуждается в подсказках вроде [DataMember]; вы можете попросить его применить либо правила BinaryFormatter (все поля, общедоступные или частные), либо правила XmlSerializer (общедоступные элементы, свойства или поля); опять же, это очень нестабильно, если ваш тип изменится!

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]

Но; другой распространенный сценарий заключается в том, что у вас есть типы, поступающие из генератора, которые вы не можете удобно редактировать, поскольку любые изменения будут потеряны при повторной генерации; для этого сценария могут быть полезны partial классов. Вы не можете добавлять атрибуты к участникам через атрибуты, но здесь может помочь [ProtoPartialMember]. Например, в отдельном файле кода:

[ProtoContract]
[ProtoPartialMember(key, memberName)]
[ProtoPartialMember(anotherKey, anotherMemberName)]
...
public partial class Order {}

Иногда у вас нет какого бы то ни было доступа к типу, поэтому добавление атрибутов любого типа невозможно. Если ваш сценарий соответствует описанию ([DataContract/[DataMember], noOrder`), то ленивый параметр должен включить это глобально:

Serializer.GlobalOptions.InferTagFromName = true;

or in v2:

RuntimeTypeModel.Default.InferTagFromNameDefault = true;

Для более сложных сценариев в v2 есть новая модель MetaType, посвященная этому, где вы можете настроить макет во время выполнения:

RuntimeTypeModel.Default.Add(typeof(Order), false)
            .Add(key, memberName).Add(anotherKey, anotherMemberName);

или если ваши ключи 1, 2, 3,... тогда просто:

   RuntimeTypeModel.Default.Add(typeof(Order), false)
            .Add(memberName, anotherMemberName, ...);

(на MetaType есть множество опций для управления всеми аспектами сериализации)

Я думаю, что здесь описано большинство вариантов!

person Marc Gravell    schedule 18.11.2011
comment
RuntimeTypeModel.Default.InferTagFromNameDefault = true; вроде работает спасибо. - person P a u l; 18.11.2011
comment
@Paul, пожалуйста, обратите внимание на акцент выше; это не стабильно при добавлении элементов, поскольку оно расположено в алфавитном порядке. Если вы добавите AardvarkCount, все будет внезапно отключено - person Marc Gravell; 18.11.2011

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

<protocontract()>
Public Class Peer
   <ProtoMember(1)>
    Public Property PacketNumber As Long
    <ProtoMember(2)>
    Public Property DateCreated As DateTime
    <ProtoMember(3)>
    Public Property Data As String 
    <ProtoMember(4)>
    Public Property OriginatingTerminal As Integer
end class

Надеюсь это поможет

person Paul Farry    schedule 17.11.2011
comment
на данный момент это человеческие руки, потому что я представляю Protobuf существующему сетевому приложению - person Paul Farry; 18.11.2011