序列化顺序&团结问题

时间:2009-01-07 06:58:17

标签: .net serialization unity-container

我有一个使用XML和自定义序列化程序的应用程序,并且最近使用Unity 1.2添加了一些DI来在我的类中设置两个属性。

现在,当我序列化类时,Unity首先序列化属性,然后依次序列化所有其他属性。

因此,如果Unity设置类属性2和3,则序列化类出现在以下orger中: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配置

<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,目前我刚刚将属性1添加到Unity配置中,所以我可以进行一些测试。

但我真正想知道的是,为什么Unity填充的属性与任何其他方法设置的属性的处理方式不同。 (反射,构造函数或属性设置器)。

1 个答案:

答案 0 :(得分:1)

那么,您的自定义序列化程序如何选择订单?你控制这个序列化器吗?还是第三方?您描述的“2,3,1,4,5”模式让我们想知道您的对象是不是“属性包”,它只是按照设置的顺序序列化数据 - 这将是高度有风险。您设置属性的顺序不应该(通常)重要。

属性没有已定义的顺序,您不应该在构建之间依赖此顺序。系统也不能保证反射与源代码的属性顺序与事实上的任何东西相比。

所以你需要以某种方式自己定义顺序,可能是按字母顺序排列(但是当有人添加AardvarkCount属性时这很脆弱),可能是通过自定义属性。

我有一个custom (binary) serializer,我使用自定义属性方法,虽然我支持某些情况下的字母。例如:

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

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

然后反射命令属性的顺序无关紧要 - 序列化程序始终按FooBar的顺序读/写数据。

(对于观察者:是的,上面的例子看起来很像WCF /数据契约与Order属性集,所以我也支持它;-p)