1

据我了解,大多数序列化/反序列化技术使用反射来创建对象并设置或获取值。那么为什么要在类中显式绑定这些属性,例如 [XmlIgnore]... 用于 xml,[Serializable]... 在二进制序列化中,[JsonPropery]...Json.Net 等。既然这些就对象而言就像横切关注点,我们不能在对象之外做同样的事情吗?

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

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

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

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

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

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

所以我计划评估某些序列化框架以实现相同的目标。我发现 Json.Net 可以给我以下

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

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

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

4

4 回答 4

1

嗯,是。XML 序列化可以处理任何具有以下两个警告的对象,这两个警告都不需要属性修饰:

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

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

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

简而言之,有几个内置的或免费提供的序列化器可以使用最少的元数据;但是,如果它们不允许您自定义流程以准确产生所需的结果,那么它们的用处将受到极大限制。所以,他们做到了。

于 2012-11-19T17:28:46.357 回答
1

通过您的编辑,除其他外引用私有字段:坦率地说,您正在扩展任何一个序列化程序将提供的功能集。您可能可以使用扩展 API 来完成其中的一些工作,但这将是很多工作,而不是 100%。如果花时间与序列化程序和调试作斗争,您将花费很多时间。

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

这样,如果两全其美,您将获得最好的。序列化程序对 DTO 很满意(您可以根据需要调整数据,通过调整 DTO 类型),并且您的域实体非常干净,完全不知道序列化问题。

于 2012-11-19T19:15:10.420 回答
0

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

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

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

于 2012-11-19T17:26:32.007 回答
0

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

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

于 2012-11-19T17:41:15.700 回答