2

XML とカスタム シリアライザーを使用するアプリケーションがあり、最近、Unity 1.2 を使用していくつかの DI を追加し、クラスに 2 つのプロパティを設定しました。

クラスをシリアル化すると、Unity によって設定されたプロパティが最初にシリアル化され、その後に他のすべてのプロパティが順番にシリアル化されます。

したがって、クラスのプロパティ 2 と 3 が Unity によって設定されている場合、シリアル化されたクラスは次の順序で出力されます: 23145

XmlSerialiser の場合、XmlElement 属性を使用して順序を設定できますが、カスタム シリアライザーは依然として間違った順序でクラスを出力しており、固定長形式であるため、順序が重要です。

Unityを使用しながら、クラスを順番にシリアル化する方法を知っている人はいますか?

ありがとう

コード例 クラス

 [Serializable]
[DataContract]
[XmlInclude(typeof(HeaderDocument))]
public class HeaderDocument
{
    [InjectionConstructor]
    public HeaderDocument()
    {
        DateTimeCreated  = DateTime.Now;
        TransactionId  = Guid.NewGuid().ToString();
        HasPayload = true;
    }

    /// <summary>Gets or sets the service name of the target service.</summary>
    [DataMember, CopyBookElement("REQUESTED-SERVICE", CopyBookDataType.String, Length = 40)]
    public string ServiceName { get; set; } 

    /// <summary>Gets or sets the entry application name of the request.</summary>
    [DataMember, CopyBookElement("CONSUMER-APPLICATION-ID", CopyBookDataType.UnsignedInteger, Length = 3)]
    public int ApplicationId { get; set; } 

    /// <summary>Gets or sets the quality of service required for the request.</summary>
    [DataMember, CopyBookElement("QUALITY-OF-SERVICE", CopyBookDataType.String, Length = 1)]
    public string QualityOfService { get; set; }

    /// <summary>Gets or sets the transaction identifier.</summary>
    [DataMember, CopyBookElement("TRANSACTION-ID", CopyBookDataType.String, Length = 36)]
    public string TransactionId { get; set; }

    /// <summary>Gets or sets the time the document was created.</summary>
    public DateTime DateTimeCreated { get; set; }

    [DataMember, CopyBookElement("HAS-PAYLOAD", CopyBookDataType.Boolean)]
    public bool HasPayload { get; set; }
}

ユニティ構成

<unity>
<typeAliases />
<containers>
  <container name="TechnicalArchitecture">
    <types>
      <type type="ILogger, ApplicationServices" mapTo="Logger, ApplicationServices" />
      <type type="HeaderDocument, ApplicationServices">
        <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
          <property name="ApplicationId" propertyType="System.Int32">
            <value value="19" />
          </property>
          <property name="QualityOfService" propertyType="System.String">
            <value value="1" />
          </property>
        </typeConfig>
      </type>
    </types>
  </container>
</containers>

私が呼び出すHeaderDocumentを構築するとき

HeaderDocument = IOC.Container.Resolve<HeaderDocument>();

カスタム serilaiser を変更する必要はありません。現在、Unity 構成にプロパティ 1 を追加したので、テストを行うことができます。

しかし、私が本当に知りたいのは、Unity によって入力されたプロパティが、他の方法によって設定されたプロパティとは異なる方法で扱われる理由です。(リフレクション、コンストラクター、またはプロパティ セッター)。

4

1 に答える 1

1

では、カスタム シリアライザーはどのように順序を選択するのでしょうか? そして、このシリアライザーを制御しますか? それともサードパーティですか?あなたが説明した「2、3、1、4、5」のパターンは、オブジェクトが「プロパティバッグ」ではないかどうか疑問に思います。設定された順序でデータをシリアル化しているだけです。これは非常に危険です。プロパティを設定する順序は (通常) 重要ではありません。

プロパティには順序が定義されていないため、ビルド間でこの順序に依存しないでください。また、システムは、リフレクションからのプロパティの順序、ソース コードからのプロパティの順序、および実際には何も保証しません。

AardvarkCountしたがって、おそらくカスタム属性を介して、おそらくアルファベット順で(ただし、誰かがプロパティを追加するとこれは脆弱です)、自分で順序を定義する必要があります。

カスタム (バイナリ) serializerがあり、カスタム属性アプローチを使用しますが、一部のシナリオではアルファベット順をサポートしています。例えば:

[ProtoContract]
public class MyClass {
    [ProtoMember(1)]
    public int Foo {get;set;}

    [ProtoMember(2)]
    public string Bar {get;set;}
}

Foo次に、リフレクションがプロパティをどの順序で並べるかは問題ではありません。シリアライザーは常に 、 の順序でデータを読み書きしますBar

(そして観察者のために: はい、上記の例は、プロパティ セットを使用した WCF / data-contracts によく似ているOrderため、私もそれをサポートします;-p)

于 2009-01-07T08:32:16.287 に答える