2

.NET リモート処理を使用してレイヤー間で DAO を渡す巨大なクライアント/サーバー WinForms アプリがありますが、これにはいくつか問題があります。

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

シリアライゼーション形式を変更すると、古いクライアントとの互換性が失われますか?

4

1 に答える 1

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を使用してリモートのシリアル化を制御する例を次に示します (単体テストの 1 つから直接取得)。これも、クライアントとサーバーの両方が同意するまで互換性がありませんが、その後の変更には耐える必要があることに注意してください(非常に拡張できるように設計されています)。それを使用する方法はたくさんあることに注意してください-明示的なメンバー表記(データコントラクトなど)または暗黙的なフィールド( などBinaryFormatter)など(その間のすべて)...これは使用方法の1つにすぎません。

[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 つのメソッドが を満たしISerializableprotobuf-netエンジンに実行を渡すだけです。定義フィールド (一意の[ProtoMember(...)]識別マーカー付き)。すでに述べたように、これらを推測することもできますが、明示的である方が安全です (脆弱性が少なくなります)。

于 2009-02-09T15:49:47.263 に答える