为什么我们需要将序列化属性修饰为类和属性,或者实现一些用于持久化数据的接口



据我所知,大多数序列化/反序列化技术都使用反射来创建对象并设置或获取值。那么,为什么要显式绑定这些属性,如[XmlIgnore]。。。对于xml,[Serializable]。。。在二进制串行化中,〔JsonPropery〕。。。Json、Net等。既然这些就像是对一个物体的交叉关注,我们就不能在物体之外做同样的事情吗?

如果关注点被分离,用户可以控制对象图/树的哪个部分需要在哪个上下文下序列化/反序列化,以及如何序列化等等?

是否有任何这样的框架将整个序列化作为方面,即在类的关注之外?

第1版:我的要求如下我的应用程序将数据存储在一个巨大的树状结构中。客户的要求是能够以xml格式序列化某些数据,并以Json格式序列化某些部分的数据(我不知道为什么会有这样的要求),我们将大多数数据以二进制形式序列化为遗留代码。

现在有一些类,其中一部分数据需要以XML格式显示,另一部分数据(也可以是XML数据或二进制序列化数据的一部分)需要以Json格式显示。

所以我正在寻找一个解决方案,其中

  1. 类不应该知道任何特定于序列化的属性,相反,序列化程序框架可以提供足够的工具,在不接触类的情况下轻松进行序列化
  2. 该框架应该允许持久化我想要的私有和公共数据。这可以特定于类或实例,也可以特定于某些上下文中实例的某些属性
    例如。
    • SaveTemplate:应该只保存树
    • SaveDocument:应保存树中的一个分支完全
    • SavePackage:应该保存整个树
  3. 应允许序列化为不同的格式,如xml、二进制、json等,用于不同的目的

所以我计划评估某些序列化框架以实现同样的目标。我找到了Json.Net,它可以给我以下

  • xml序列化一样,不能为公共属性放置序列化标记
  • 向后兼容二进制序列化。即,我不必更改二进制序列化接口实现
  • 不需要无参数构造函数

但是我仍然需要上面第2)点和第3)点中提到的能力。我还没有详细研究Json.Net或任何其他框架。

有什么框架可以帮助我实现同样的目标吗?

在您的编辑中,引用私有字段以及其他内容:坦率地说,您正在扩展任何一个序列化程序将提供的功能集。您可能可以使用扩展API来完成其中的一些工作,但这将是大量的工作,而不是100%。如果花费大量时间对抗序列化程序和调试的话。

在这种情况下,有一个更好的解决方案:编写一组与域实体完全无关的DTO类型。序列化/反序列化DTO-随意注释DTO,就像没有明天一样:它们的唯一目的是表达序列化意图。然后只需映射到DTO和实体类型。

这样,你就能两全其美。序列化程序对DTO很满意(您可以通过调整DTO类型来根据需要塑造数据),并且您的域实体非常干净,完全不知道序列化问题。

嗯,是的。XML序列化可以在具有以下两个注意事项的任何对象上工作,这两个注意都不需要属性修饰:

  • 对象必须有一个公共的、无参数的构造函数
  • 所有应序列化的信息都必须位于公开可见的字段或属性中

简单。但是,没有属性的XML序列化会为对象生成"默认"的XML结构。如果您试图使通过序列化对象生成的XML类符合预先存在的XML文档格式,如SOAP请求、HTML或XAML,则此默认结构可能不起作用,因此必须使用任一属性对其进行自定义,告诉内置序列化器引擎如何调整其生成的内容,或者一个自定义序列化例程,它基本上覆盖内置引擎,并完全按照您的意愿执行操作。

二进制序列化在最基本的情况下,需要将一个单独的属性Serializable应用于类本身。这只不过是向编译器或运行时提示,该类的定义应包含在为此目的创建的一组"序列化程序集"中。然而,同样,如果你只是告诉它对象可以被序列化,而不告诉它如何,你就会得到默认行为;字段可能包含您不想要的内容,或者序列化程序可能遇到无法序列化的问题。

简言之,有几个内置的或免费提供的序列化程序,它们将使用最低限度的元数据;然而,如果它们不允许您自定义流程以产生所需的结果,那么它们的有用性将受到严重限制。所以,他们确实如此。

通常,您的类/实例会有许多私有字段和其他与XML无关的公共属性。

像[XMLElement(…)]这样的属性也用于定义永远不会更改的XML元素的名称。即使更改了类中属性的名称,序列化和去序列化仍然有效。

如果您不想使用这些元素,您可以自由地实现自己的XMLWriter或XMLReader。您还可以创建XMLWriter的实例,并使用它的Write方法来编写您想要的任何内容。

是。如果您不介意在运行时配置XmlAttributeOverrides实例并将其传递到重载构造函数中,则可以使用XmlSerializer执行此操作。使用这种方法,您可以对XML属性执行所有可以执行的操作,但关键是缓存并重用在执行此操作时创建的序列化程序(不要每次都创建一个新实例)。

对于二进制文件,protobuf-net允许您在运行时通过RuntimeTypeModel(例如RuntimeTypeModel.Default.Add(typeof(SomeClass), false).Add("X", "Y", "Z");)对其进行配置。然而,实际情况是,序列化程序通常很复杂,有很多选项。在大多数情况下,只需简单地将配置与实体保持在一起即可。但是是的:有些确实允许您在运行时完全配置它们。

相关内容

  • 没有找到相关文章

最新更新