implementando ISerializable para control de versiones

Considere el siguiente tipo de class de POD:

public class Price { public decimal OfferPrice { get; set; } } 

los objects de esta class se recuperan de un server, así que decoremos con Serializable

 [Serializable] public class Price { public decimal OfferPrice { get; set; } } 

Ahora hay dos clientes en diferentes máquinas que recuperan estos objects. No enviarán precios. Todos reciben una copy de la asamblea de Price.

Ahora la class se expande con BonusPrice.

 [Serializable] public class Price { public decimal OfferPrice { get; set; } public decimal BonusPrice { get; set; } } 

El nuevo ensamblaje se implementa en el server, a uno de los clientes pero NO al otro. Por lo tanto, el cliente con versiones anteriores se bloqueará al (de) serializar los objects Precio.

El cliente con la versión anterior no necesita el campo BonusPrice, por lo que sería bueno que siga funcionando cuando hay una diferencia de versión. Por lo tanto, estoy pensando en implementar ISerializable desde el principio, así que la primera y la segunda versión se verían así:

 // version 1.0 [Serializable] public class Price : ISerializable { protected Price(SerializationInfo info, StreamingContext context) { OfferPrice = info.GetDecimal("op"); } [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("op", OfferPrice); } } // version 2.0 [Serializable] public class Price : ISerializable { protected Price(SerializationInfo info, StreamingContext context) { OfferPrice = info.GetDecimal("op"); BonusPrice = info.GetDecimal("bp"); } [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("op", OfferPrice); info.AddValue("bp", BonusPrice); } } 

Entonces, cuando el único cliente no se actualice a la versión 2, seguirá deserializando únicamente OfferPrice y no se bloqueará. Cuando se actualice en algún momento, usará BonusPrice automáticamente.

Mi pregunta: ¿implementar ISerializable es una buena forma de ir con el control de versiones cuando solo se están leyendo objects? ¿Cómo se resuelven usualmente estos problemas?

Puede usar OptionalFieldAttribute para controlar el control de versiones de BinaryFormatter y SoapFormatter .

OptionalFieldAttribute tiene la propiedad VersionAdded . En la versión 2.0 de .NET Framework, esto no se usa. Sin embargo, es importante establecer esta propiedad correctamente para garantizar que el tipo sea compatible con futuros motores de serialization.

La propiedad indica qué versión de un tipo se ha agregado un campo determinado. Debe incrementarse exactamente en uno (comenzando en 2) cada vez que se modifique el tipo

También hay otras forms como las ISerializable serialization, SerializationBinder, ISerializable , etc.

Refiérase a Serialización tolerante a la versión para más información.

Desde mi punto de vista, está intentando mezclar dos versiones de protocolos en un contrato. En su ejemplo, funciona, pero en la práctica a menudo es difícil unificar el nuevo protocolo, por lo que es mejor dejarlos separados. En otras palabras, su server tiene que admitir ambas versiones de forma independiente. Eche un vistazo a las versiones del protocolo OData