2

両方のコードベースを変更できるサーバー クライアント アプリケーションがあります。クライアントは多数の Web サービスを介してサーバーと通信します。私は Web 参照システムを介してサーバー側で定義されたいくつかのクラスを共有します。ネットワーク上では、データは XML (SOAP) を使用して送信されます。また、 を使用してディスク上のデータの一部を保存しXmlSerializerます。

パフォーマンスの問題が増えているため、プロトコル バッファと protobuf-net に目を向けて、より洗練されたシリアライザーに移行したいと考えています。現在、protobuf-net v2 (r480、.NET 3.5) を使用しています。

ProtoContract私が抱えていると思われる問題は、Web 参照システムを介して共有されるクラスが、 や などのカスタム クラス/メンバー属性を保持しないことですProtoMember
(しかし、シリアライザー システムは通常の をスローせSystem.InvalidOperationException: Type is not expected, and no contract can be inferred、空のストリームを残します。クライアント側で生成されたクラスが としてマークされているためpartialですか?)

例、サーバー側:

[ProtoContract]
public class CommentStruct
{
    [ProtoMember(1)] public int id;
    [ProtoMember(2)] public DateTime time;
    [ProtoMember(3)] public string comment;
    [ProtoMember(4)] public int session;
}

クライアント側 (生成コード):

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org")]
public partial class CommentStruct {
    private int idField;
    private System.DateTime timeField;
    private string commentField;
    private int sessionField;

    /// <remarks/>
    public int id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }
    [...]

ProtoPartialMemberクライアント側の追加のクラス ファイルを使用して、この問題を回避することができました。

[ProtoContract,
ProtoPartialMember(1, "id"),
ProtoPartialMember(2, "time"),
ProtoPartialMember(3, "comment"),
ProtoPartialMember(4, "session")]
public partial class CommentStruct
{
}

ここでの主な懸念は、コードの重複を避けるために別の方法でこれを行うことができるかということです。
もう 1 つは、継承サポートなどの protobuf-net 機能を利用できないでしょうか?

protobuf-net Visual Studio アドインに関する情報を見つけました。しかし、Marc Gravell がそれを「後付け」と表現しているように、私はそれを使用することに消極的です。さらに、私の共同開発者の何人かは、アドインをサポートしていない VS Express エディションを使用しています。

編集:私の主な重複の懸念は、サーバー側のクラス定義とクライアント側の部分クラス属性で、クラスメンバーとprotobuf-net属性を2回指定する必要があることです。

4

1 に答える 1

1

用語の細かい点として、ここでは「共有」という言葉を避けます。「共有」は通常、ライブラリとして (機能する) を意味するためです。

エラーが発生しない理由はpartial;とは関係ありません。単純に、protobuf-net が他のライブラリの属性を適度に喜んで使用しているということです... 当然のことです。たとえば、[XmlType]/[XmlElement(Order=n)]および[DataContract]/で動作し[DataMember(Order=n)]ます。ただし、ここで WSDL から生成されたコードには Order=n が含まれていないため、シリアル化が必要なメンバーとして認識されません (実際には番号が必要です)。

[ProtoPartialMember(...)]あなたが言及したように)使用法はこれを回避する1つの方法です。他の protobuf-net の使用を制限するものではありません。[ProtoInclude(...)]それでも機能します(継承について言及しているため)。実際、protobuf-net のすべては、実行時に属性なしで完全に構成することもできます ( 経由)RuntimeTypeMode。再重複:クラス名以外は重複していません。おそらく、[ProtoInclude(...)]は と少し重複して[XmlInclude(...)]いますが、それほど多くはありません。

ついでにこのフレーズを使用したと信じてよろしいのですが、アドインの使用法を説明する主な方法が「後付け」であるかどうかはわかりません。明確にするために: protobuf-net は主に、ツールから生成するのではなく、コード ファースト (おそらく属性を使用) の一般的な .NET イディオムに適合することを目的としています。どちらからでも機能します。

もちろん、おそらく最も簡単なオプションは、利用可能な場合、単に .dll または .cs を共有することです。これは WCF /DataContractSerializerで問題なく動作しますが、古い「Web 参照」Web サービスがこれを気に入っているかどうかはわかりません。もちろん、古いスタイルの「Web 参照」(「asmx」) の一部として protobuf-net を使用するためのプラグイン サポートもありません。

于 2012-07-11T10:15:32.167 に答える