1

私の理解では、シリアライゼーション/デシリアライゼーション手法のほとんどは、リフレクションを使用してオブジェクトを作成し、値を設定または取得します。では、[XmlIgnore]... xml、[Serializable]... バイナリ シリアライゼーション、[JsonPropery]... Json.Net などの属性をクラスで明示的にバインドするのはなぜですか。これらはオブジェクトに関する限り横断的な懸念のようなものなので、オブジェクトの外で同じことを行うことはできませんか?

懸念事項が分離されている場合、ユーザーは、オブジェクト グラフ/ツリーのどの部分をどのコンテキストでどのようにシリアライズ/デシリアライズする必要があるかなどを制御できますか?

シリアライゼーション全体を側面として、つまりクラスの関心の外にするようなフレームワークはありますか?

Edit1:私の要件は次のとおりです。私のアプリケーションは、データを巨大なツリー構造に格納します。顧客の要件は、特定のデータを xml 形式でシリアル化し、データの特定の部分を Json でシリアル化できるようにすることであり (なぜそのような要件が必要なのかわかりません)、ほとんどのデータをレガシー コードとしてバイナリでシリアル化しています。

データの一部を XML 形式で表示する必要があるクラスと、別の部分 (これらは xml データまたはバイナリ シリアル化データの一部である場合もあります) を Json で表示する必要があるクラスがあります。

だから私は解決策を探しています

  1. クラスは、シリアライゼーション固有の属性を認識する必要はありません。代わりに、シリアライザー フレームワークは、クラスに触れずにシリアライゼーションを簡単に行うための十分なツールを提供できます。
  2. フレームワークは、私が望んでいたプライベート データとパブリック データの両方を永続化できるようにする必要があります。これは、クラスまたはインスタンスに固有の場合もあれば、あるコンテキストのインスタンスの一部のプロパティに固有の場合もあります。
    例えば
    • SaveTemplate: ツリーの各ブランチからいくつかのノードのみを保存する必要があります
    • SaveDocument: ツリーから 1 つのブランチを完全に保存する必要があります
    • SavePackage: ツリー全体を保存する必要があります。
  3. さまざまな目的で、xml、バイナリ、json などのさまざまな形式にシリアル化できるようにする必要があります。

そのため、特定のシリアル化フレームワークを評価して同じことを達成することを計画しています。私は次のことができるJson.Netを見つけました

  • xml serializationのように、パブリック プロパティにシリアル化タグを配置する必要はありません。
  • Binary Serialization への下位互換性。つまり、バイナリ シリアライゼーション インターフェイスの実装を変更する必要はありません。
  • パラメーターのないコンストラクターは必要ありません。

ただし、上記の 2) と 3) で述べた機能はまだ必要です。Json.Net やその他のフレームワークについてはまだ詳しく調べていません。

同じことを達成するのに役立つフレームワークはありますか?

4

4 に答える 4

1

はい、そうです。XMLシリアル化は、次の2つの警告があり、どのオブジェクトでも機能します。どちらも属性の装飾は必要ありません。

  • オブジェクトには、パラメーターのないパブリックコンストラクターが必要です。
  • シリアル化する必要のあるすべての情報は、公開されているフィールドまたはプロパティに含まれている必要があります。

簡単。ただし、属性を使用しないXMLシリアル化では、オブジェクトの「デフォルト」のXML構造が生成されます。オブジェクトをシリアル化して生成されたXMLクラスを、SOAPリクエスト、HTML、XAMLなどの既存のXMLドキュメント形式に準拠させようとしている場合、このデフォルトの構造はおそらく機能しないため、カスタマイズする必要がありますいずれかの属性を使用するか、組み込みのシリアライザーエンジンに生成内容を微調整する方法を指示するか、基本的に組み込みのエンジンをオーバーライドして必要な処理を正確に実行するカスタムシリアル化ルーチンを使用します。

バイナリシリアル化は、最も基本的に、クラス自体に適用される単一の属性、Serializableを必要とします。これは、このクラスの定義を、その目的のために作成された一連の「シリアル化アセンブリ」に含める必要があるというコンパイラまたはランタイムへのヒントにすぎません。ただし、繰り返しになりますが、オブジェクトをシリアル化できることを伝え、その方法を伝えない場合は、デフォルトの動作になります。不要なフィールドが含まれている場合や、シリアライザーがシリアル化できないもので問題が発生する場合があります。

要するに、最小限のメタデータで動作する組み込みまたは無料で利用可能なシリアライザーがいくつかあります。ただし、必要な結果を正確に生成するようにプロセスをカスタマイズできない場合、それらの有用性は大幅に制限されます。だから、彼らはそうします。

于 2012-11-19T17:28:46.357 に答える
1

あなたの編集では、特にプライベートフィールドを参照しています。率直に言って、シリアライザーが提供する機能セットを拡張しています。おそらく拡張 API を使用してその一部を実行できますが、100% ではなく、多くの作業が必要になります。シリアライザーとの戦いとデバッグに時間がかかる場合は、多くの時間を費やすことになります。

このような場合、はるかに優れた解決策があります。ドメイン エンティティとはまったく関係のない一連の DTO タイプを記述します。DTO のシリアライズ/デシリアライズ - 明日はないように、DTO に自由に注釈を付けてください。それらの唯一の目的は、シリアライゼーションの意図を表現することです。次に、DTO およびエンティティ タイプとの間でマッピングします。

このようにして、両方の世界で最高の結果が得られます。シリアライザーは DTO に満足しており (そして、DTO の型を調整することで、データを好きなように形作ることができます)、ドメイン エンティティは非常にクリーンで、シリアライゼーションの問題をまったく認識していません。

于 2012-11-19T19:15:10.420 に答える
0

はい。実行時にインスタンスを構成し、それをオーバーロードされたコンストラクターに渡すことをXmlSerializer気にしない場合は、これを行うことができます。XmlAttributeOverridesこのアプローチでは、XML属性で実行できるすべてのことを実行できますが、これを実行するときに作成したシリアライザーをキャッシュして再利用することが重要です(毎回新しいインスタンスを作成しないでください)。

RuntimeTypeModelバイナリの場合、protobuf-netを使用すると、たとえば、を介して実行時に設定できますRuntimeTypeModel.Default.Add(typeof(SomeClass), false).Add("X", "Y", "Z");。ただし、実際には、シリアライザーは多くの場合、多くのオプションを備えた複雑なものです。ほとんどの場合、エンティティを使用して構成を維持する方が簡単です。しかし、そうです。実行時に完全に構​​成できるものもあります。

于 2012-11-19T17:41:15.700 に答える
0

通常、クラス/インスタンスには、XML には関係のない多くのプライベート フィールドやその他のパブリック プロパティがあります。

[XMLElement(...)] のような属性も、変更されない XML 要素の名前を定義するために使用されます。クラス内のプロパティの名前を変更しても、シリアル化と逆シリアル化は機能します。

これらの要素を使用したくない場合は、独自の XMLWriter または XMLReader を自由に実装できます。XMLWriter のインスタンスを作成し、その Write メソッドを使用して、必要なものを書き込むこともできます。

于 2012-11-19T17:26:32.007 に答える