这里提到protobuf-net 可以像 SAX 解析器一样使用,但我找不到不需要或多或少完整描述要解析的对象的示例。
(跳到第2 点)问题,1)只是提供一些上下文)
1)也许我应该先提供一些背景信息:
我目前在我的项目中使用 JSON.Net,并创建了几个 JSONConverter 来自定义各种类型的序列化方式——基本上所有主要类型都有手写的序列化指令(ReadProperty、ReadValue 等)。
我为什么这样做以及在哪里这样做的一些例子:
- 我有一个
MetaType
类来描述某些Value
对象在运行时的行为。这些Value
对象有一个Type
被序列化的属性。一个ConverterMetaType
在序列化这个属性时只返回该属性的名称,反序列化时使用该名称获取对应MetaType
的inf。这样做的原因是类型的名字就够了,MetaType
类序列化太麻烦,生成的JSON更紧凑。 - 一些对象的集合包含不需要序列化的值,因为我可以根据
MetaType
它们不存在的时间重新创建它们。转换器过滤这些集合并仅存储那些不是默认值的值 - 而 JSON.Net 具有防止属性在设置为默认值时被序列化的属性,我不知道任何内置方法来过滤默认值从一个集合。
我的目标是什么:
由于我已经有这么多手写的序列化代码,我想摆脱 OR-Mapper。这样做的原因是我可以更轻松地创建可以读取旧 JSON 格式并执行必要的迁移步骤(添加数据、忽略不再需要的数据等)的迁移器。使用 OR-Mapper,我需要旧类型来解析旧格式,然后将旧类型转换为新类型——这是一种有效的策略,但是因为我有手写代码,所以我可以执行非常精细的迁移步骤并对几乎任何变化。基本上更强大,我不需要旧的对象模型。
2)那么实际的问题是什么?
我可以使用 protobuf-net 或多或少地从流中手动读取/写入数据,或者以其他 方式对(反)序列化具有类似的能力(例如 RuntimeTypeModel?)
要使用上面的示例:
- 我有一个具有 type 属性的对象
MetaType
,但不是序列化整个对象MetaType
,我只想存储一个字符串或 ID。反序列化时,使用字符串或ID来获取正确的MetaType
(<=我只需要解析器存储/读取ID,我会做查找) - 我希望能够在序列化时过滤集合,并且只存储满足特定条件的对象。
- 我希望能够通过读取它们并根据需要迁移数据来支持旧格式。我已经存储了一个版本号,可用于分支反序列化或创建不同类型的对象(v1、v2)——尽管如果我不需要使用我的对象模型的多个版本,我更喜欢它,迁移在解析器级别(在创建对象之前)会很棒。
一个伪代码示例(如果上面没有意义):
int version = Reader.ReadInt()
// [...] decide how to proceed based on version
var typeName = Reader.ReadString()
var type = MetaType.For(typeName)
// [...] read some more properties
return new ValueObject(type, property1, property2)
protobuf-net 是否可能/推荐类似的东西?(示例/文档或教程的链接会很棒——我知道有一个 ProtoReader 类,但我不确定我是否应该使用它/如果我足够聪明,可以在没有任何文档的情况下使用它)
编辑:
在此处添加 Marc 的评论以获得更好的可见性: