Migrowanie do platformy protobuf-net (binarnej)
Biblioteka protobuf-net to serializator oparty na kontraktach dla platformy .NET, który używa formatuserialization protokołu binarnego. Interfejs API jest zgodny z typowymi wzorcami platformy .NET i jest zasadniczo porównywalny z XmlSerializer
elementami i DataContractSerializer
.
Niektóre zachowania i funkcje narzędzia protobuf-net będą godne uwagi podczas migracji z BinaryFormatterprogramu , a wiele scenariuszy wymaga zastosowania atrybutów do elementów członkowskich.
- Domyślnie zarówno typy publiczne, jak i inne niż publiczne są serializowalne, a serializator oczekuje konstruktora bez parametrów.
- Protobuf-net wymaga, aby każdy typ można serializować z atrybutem
[ProtoContract]
; ten atrybut może opcjonalnie określićSkipConstructor = true
właściwość, co eliminuje potrzebę dowolnego konstruktora. - Każde pole niestatyczne z możliwością serializacji i właściwość musi być oznaczona adnotacjami z atrybutem
[ProtoMember(int identifier)]
. Nazwy składowych nie są kodowane w danych. Zamiast tego użytkownicy muszą wybrać dodatnią liczbę całkowitą, aby zidentyfikować każdy element członkowski, który musi być unikatowy w obrębie tego typu. - Dziedziczenie musi być jawnie zadeklarowane za pośrednictwem
[ProtoInclude(...)]
atrybutu dla każdego typu ze znanymi podtypami. - Pola tylko do odczytu są domyślnie obsługiwane.
- Alternatywnie niektóre nieprzypisania typów podobnych do krotki są rozpoznawane przez wzorzec konstruktora; typ z konstruktorem, który ma parametry zgodne (według nazwy) wszystkich zadeklarowanych publicznych elementów członkowskich, zostanie zinterpretowany jako krotka, a kolejność parametrów zostanie użyta do wywnioskowania identyfikatora dla tego elementu członkowskiego.
- Korzystanie z
protobuf-net.BuildTools
pakietu w czasie projektowania jest zdecydowanie zalecane. Oferuje to ostrzeżenia w czasie kompilacji o typowych błędach.
Migracja krok po kroku
- Znajdź wszystkie użycia elementu
BinaryFormatter
. - Upewnij się, że serialization ścieżki kodu są objęte testami, aby można było zweryfikować zmiany i uniknąć wprowadzania usterek.
- Zainstaluj
protobuf-net
pakiet (i opcjonalnieprotobuf-net.BuildTools
). - Znajdź wszystkie typy, które są serializowane za pomocą polecenia
BinaryFormatter
. - W przypadku typów, które można modyfikować:
- Dodaj adnotację do
[ProtoContract]
atrybutu wszystkich typów oznaczonych za pomocą[Serializable]
interfejsu lub zaimplementuj goISerializable
. Jeśli te typy nie są widoczne dla innych aplikacji (na przykład: piszesz bibliotekę), która może używać różnych serializatorów, takich jakDataContractSerializer
, możesz usunąć[Serializable]
adnotacje iISerializable
. - W przypadku typów pochodnych zastosuj się
[ProtoInclude(...)]
do ich typów bazowych (zobacz poniższy przykład). - Dla każdego typu, który deklaruje dowolny konstruktor, który akceptuje parametry, dodaj konstruktor bez parametrów lub określ
SkipConstructor = true
atrybut.[ProtoContract]
Pozostaw komentarz, który wyjaśnia wymaganie protobuf-net (więc nikt nie usuwa go przypadkowo). - Oznacz wszystkie elementy członkowskie (pola i właściwości), które chcesz serializować za pomocą polecenia
[ProtoMember(int identifier)]
. Wszystkie identyfikatory muszą być unikatowe w obrębie jednego typu, ale te same liczby mogą być ponownie używane w podtypach, jeśli jest włączone dziedziczenie.
- Dodaj adnotację do
- W przypadku typów, których nie można modyfikować:
- W przypadku typów udostępnianych przez samą platformę .NET można użyć interfejsu
ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type)
API, aby sprawdzić, czy są one natywnie obsługiwane przez platformę protobuf-net. - Możesz utworzyć obiekty dedykowanego transferu danych (DTO) i odpowiednio je mapować (można użyć niejawnego operatora rzutowania).
- Użyj interfejsu
RuntimeTypeModel
API, aby zdefiniować wszystkie dozwolone atrybuty.
- W przypadku typów udostępnianych przez samą platformę .NET można użyć interfejsu
- Zastąp użycie elementu ciągiem
BinaryFormatter
ProtoBuf.Serializer
.
-[Serializable]
+[ProtoContract]
+[ProtoInclude(2, typeof(Point2D))]
public class Point1D
{
+ [ProtoMember(1)]
public int X { get; set; }
}
-[Serializable]
+[ProtoContract]
public class Point2D : Point1D
{
+ [ProtoMember(2)]
public int Y { get; set; }
}
Współpracuj z nami w serwisie GitHub
Źródło tej zawartości można znaleźć w witrynie GitHub, gdzie można również tworzyć i przeglądać problemy i żądania ściągnięcia. Więcej informacji znajdziesz w naszym przewodniku dla współtwórców.