为版本控制实现ISerializable

时间:2014-11-11 08:08:42

标签: c# .net version-control versioning

考虑以下POD类型:

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

从服务器中检索此类中的对象,因此请使用Serializable

进行装饰
[Serializable]
public class Price { public decimal OfferPrice { get; set; } }

现在,在不同机器上有两个客户端检索这些对象。他们不会发价。他们都得到了普莱斯大会的副本。

现在用BonusPrice扩展了类。

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

新程序集部署到服务器,其中一个客户端而不是另一个客户端。 因此,当(de)序列化Price对象时,旧的版本化客户端将崩溃。

具有旧版本的客户端不需要BonusPrice字段,因此当存在版本差异时它会继续工作会很好。 因此,我想从一开始就实现ISerializable,所以第一个和第二个版本看起来像:

// 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);
  }
}

所以现在当一个客户端没有更新到版本2时,它仍然会继续反序列化OfferPrice并且不会崩溃。如果在某些时候更新,它将自动使用BonusPrice。

我的问题:当只读取对象时,实现ISerializable是一种使用版本控制的好方法吗? 这些问题通常是如何解决的?

2 个答案:

答案 0 :(得分:2)

您可以使用OptionalFieldAttribute来控制BinaryFormatterSoapFormatter的版本控制。

  

OptionalFieldAttribute 具有 VersionAdded 属性。在.NET Framework 2.0版中,未使用此选项。但是,正确设置此属性以确保该类型与将来的序列化引擎兼容非常重要。

     

该属性指示给定字段的类型版本   添加。每次应该增加一个(从2开始)   类型被修改的时间

还有其他方法,如序列化回调,SerializationBinder,ISerializable等。

有关详细信息,请参阅Version Tolerant Serialization

答案 1 :(得分:1)

从我的角度来看,你试图在一个合同中混合两个协议版本。在你的例子中它可行,但在实践中通常很难统一新协议,所以最好将它们分开。换句话说,您的服务器必须独立支持这两个版本。看看OData Protocol Versioning