添加自动属性会影响远程处理吗?

时间:2009-02-09 15:45:29

标签: c# serialization remoting

我们有一个庞大的客户端/服务器WinForms应用程序,它使用.NET远程处理在层之间传递DAO,这有一些问题。

  1. 在我到达之前很久,所有DAO都被定义为使用字段而不是属性,并且您无法将字段绑定到控件。
  2. 向DAO添加字段或属性会更改序列化格式,需要双客户端/服务器部署,这对我们来说比客户端或服务器部署要困难得多(我们必须解决医生的日程安排以最大限度地减少停机时间)
  3. 使用一个简单,设计和想象的例子,将改变对象:

    public class Employee
    {
        public int ID;
        public string Name;
        public DateTime DateOfBirth;
    }
    

    到此:

    public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime DateOfBirth { get; set; }
    }
    

    更改序列化格式,破坏与旧客户端的兼容性?

1 个答案:

答案 0 :(得分:1)

重要编辑:这应该兼容并允许绑定?

public class Employee
{
    private int id;
    private string name;
    private DateTime dateOfBirth;
    public int ID { get {return id;} set {id = value;} }
    public string Name { get {return name;} set {name = value;} }
    public DateTime DateOfBirth { get {return dateOfBirth;}
         set {dateOfBirth = value;} }
}

当然值得一试,不是吗?

是的,如果客户端/服务器不同步,这将导致问题。

.NET远程处理使用BinaryFormatterm(没有定制的ISerializable实现)使用字段名称。使用自动属性会破坏字段名称。

只要您同时更新客户端和服务器,它就应该可以工作。另一种选择是使用与名称无关的序列化,例如protobuf-net。如果您愿意,我可以提供一个示例(它支持ISerializable用法)。

(顺便说一句,添加属性会影响BinaryFormatter,因为它是基于字段的)


根据要求,这是使用protobuf-net来控制远程序列化的示例(直接从我的unit tests之一获取);请注意,在客户端和服务器都同意之前,这是不兼容的,但在此之后应该承受更改(它的设计非常易于扩展)。请注意,有很多方法可以使用它 - 显式成员表示法(如数据合同)或隐式字段(如BinaryFormatter)等等(中间的所有内容)...这只是 one < / strong>使用它的方式:

[Serializable, ProtoContract]
public sealed class ProtoFragment : ISerializable
{
    [ProtoMember(1, DataFormat=DataFormat.TwosComplement)]
    public int Foo { get; set; }
    [ProtoMember(2)]
    public float Bar { get; set; }

    public ProtoFragment() { }
    private ProtoFragment(
        SerializationInfo info, StreamingContext context)
    {
        Serializer.Merge(info, this);
    }
    void  ISerializable.GetObjectData(
        SerializationInfo info, StreamingContext context)
    {
        Serializer.Serialize(info, this);
    }
}

这里,底部2方法满足ISerializable,并简单地将执行传递给protobuf-net引擎。 [ProtoMember(...)]定义字段(具有唯一标识标记)。如前所述,它也可以推断出这些,但它更明确更安全(更不易碎)。