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

发布于 2024-07-13 21:43:02 字数 604 浏览 6 评论 0原文

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

  1. 早在我到达这里之前,所有 DAO 就被定义为使用字段而不是属性,并且您无法将字段绑定到控件。
  2. 向 DAO 添加字段或属性会改变序列化格式,需要双客户端/服务器部署,这对我们来说比客户端或服务器部署要困难得多(我们必须根据医生的日程安排来尽量减少停机时间)。

使用一个简单、人为且虚构的示例,将对象从这样更改

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

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

We have a huge client/server WinForms app that uses .NET remoting to pass DAOs between the layers, which has a few problems.

  1. All of the DAOs were defined to use fields instead of properties long before I got here, and you can't bind fields to controls.
  2. Adding fields or properties to a DAO changes the serialization format, requiring a dual client/server deployment, which is much more difficult for us than either a client or server deployment (we have to work around doctors' schedules to minimize downtime).

Using a simple, contrived, and imaginary example, would changing the object from this:

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

to this:

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

change the serialization format, breaking compatibility with older clients?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花海 2024-07-20 21:43:02

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

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,它(没有定制的 ISerialized 实现)使用字段名称。 使用自动属性会破坏字段名称。

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

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


根据要求,这里是使用protobuf-net 来控制远程处理序列化(直接取自我的 单元测试); 请注意,在客户端和服务器都同意之前,这也将是不兼容的,但应该能够承受此后的更改(它被设计为非常可扩展)。 请注意,有很多使用它的方法 - 显式成员表示法(如数据契约)或隐式字段(如 BinaryFormatter)等(介于两者之间的一切)...这只是 使用它的一种方式:

[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 个方法满足 ISerialized,并且只需将执行传递给 protobuf-net 引擎。 [ProtoMember(...)] 定义字段(具有唯一的标识标记)。 正如已经说过的,它也可以推断出这些,但明确地更安全(不那么脆弱)。

Important edit: this should be compatible and allow binding?

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

Certainly worth a try, no?

Yes, this will cause problems if client/server are out of sync.

.NET remoting uses BinaryFormatterm which (without a bespoke ISerializable implementation) uses the field names. Using automatic properties breaks the field names.

As long as you update client and server at the same time, it should work. Another option is to use name-independent serialization, such as protobuf-net. I can provide an example if you want (it supports ISerializable usage).

(by the way, adding properties should not affect BinaryFormatter, since it is field-based)


As requested, here's an example of using protobuf-net to control remoting serialization (taken directly from one of my unit tests); note that this will also be incompatible until both client and server agree, but should withstand changes after that (it is designed to be very extensible). Note that there are lots of ways of using it - either explicit member notation (like data-contracts) or implicit fields (like BinaryFormatter), etc (everything in between)... this is just one way of using it:

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

Here, the bottom 2 methods satisfy ISerializable, and simply pass execution to the protobuf-net engine. The [ProtoMember(...)] defines fields (with unique identification markers). As already stated, it can also infer these, but it is safer (less brittle) to be explicit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文