Migración a protobuf-net (binario)
La biblioteca protobuf-net es un serializador basado en contrato para .NET que usa el formato de búferes de protocoloserialization binario. La API sigue los patrones típicos de .NET y es ampliamente comparable a XmlSerializer
y DataContractSerializer
.
Algunos comportamientos y características de protobuf-net serán notables durante las migraciones desde BinaryFormatter y muchos escenarios requieren aplicar atributos a los miembros.
- De forma predeterminada, tanto los tipos públicos como no públicos se pueden serializar y el serializador que espera un constructor sin parámetros.
- protobuf-net requiere que todos los tipos serializable se anoten con el atributo
[ProtoContract]
; este atributo puede especificar opcionalmente la propiedadSkipConstructor = true
, que elimina la necesidad de cualquier constructor determinado. - Todos los campos no estáticos serializables y una propiedad deben anotarse con el atributo
[ProtoMember(int identifier)]
. Los nombres de miembro no están codificados en los datos. En su lugar, los usuarios deben elegir un entero positivo para identificar a cada miembro que debe ser único en ese tipo. - La herencia debe declararse explícitamente a través del atributo
[ProtoInclude(...)]
en cada tipo con subtipos conocidos. - Los campos de solo lectura se admiten de forma predeterminada.
- Como alternativa,algunos tipos similares a tupla sin atributos son reconocidos por el patrón del constructor; un tipo con un constructor que tiene parámetros que coinciden (por nombre) con todos los miembros públicos declarados se interpretará como una tupla, y el orden de los parámetros se utilizará para inferir el identificador de dicho miembro.
- Se recomienda encarecidamente usar el paquete en tiempo de diseño
protobuf-net.BuildTools
; esto ofrece advertencias en tiempo de compilación de errores comunes.
Migración paso a paso
- Busque todos los usos de
BinaryFormatter
. - Asegúrese de que las rutas de acceso al código serialization estén cubiertas con pruebas, para que pueda verificar los cambios y evitar la introducción de errores.
- Instale el paquete
protobuf-net
(y, opcionalmenteprotobuf-net.BuildTools
, ). - Busque todos los tipos que se serializan con
BinaryFormatter
. - En los tipos que pueda modificar:
- Anotar con el atributo
[ProtoContract]
todos los tipos marcados con[Serializable]
o implementar la interfaz deISerializable
. Si estos tipos no se exponen a otras aplicaciones (por ejemplo: escribe una biblioteca) que pueden usar serializadores diferentes comoDataContractSerializer
, puede quitar las anotaciones[Serializable]
yISerializable
. - En el caso de los tipos derivados, aplique
[ProtoInclude(...)]
a sus tipos base (vea el siguiente ejemplo). - En todos los tipos que declaren cualquier constructor que acepte parámetros, agregue un constructor sin parámetros, o bien especifique
SkipConstructor = true
en el atributo[ProtoContract]
. Deje un comentario que explique el requisito de protobuf-net (para que nadie lo quite por accidente). - Marque todos los miembros (campos y propiedades) que desea serializar con
[ProtoMember(int identifier)]
. Todos los identificadores deben ser únicos dentro de un solo tipo, pero los mismos números se pueden volver a usar en subtipos, siempre que la herencia esté habilitada.
- Anotar con el atributo
- En el caso de los tipos que no se pueden modificar:
- En el caso de los tipos que proporciona el propio .NET, puede usar
ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type)
API para comprobar si son compatibles de forma nativa con protobuf-net. - Puede crear objetos de transferencia de datos dedicados (DTO) y asignarlos en consecuencia (podría usar el operador de conversión implícito para hacerlo).
- Use la
RuntimeTypeModel
API para definir todo lo que permiten los atributos.
- En el caso de los tipos que proporciona el propio .NET, puede usar
- Reemplace el uso de
BinaryFormatter
porProtoBuf.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; }
}
Colaborar con nosotros en GitHub
El origen de este contenido se puede encontrar en GitHub, donde también puede crear y revisar problemas y solicitudes de incorporación de cambios. Para más información, consulte nuestra guía para colaboradores.