跳到主要内容
版本:dev

代码生成

Fory 在构建时为 Dart 类生成快速序列化器代码。为模型添加注解并运行 build_runner,其余工作由 Fory 完成。

第 1 步:为模型添加注解

为每个需要序列化的类添加 @ForyStruct()。在文件顶部包含生成的 part 指令。

import 'package:fory/fory.dart';

part 'models.fory.dart';

()
class Address {
Address();

String city = '';
String street = '';
}

()
class User {
User();

String name = '';

(type: Int32Type())
int age = 0;
Address address = Address();
}

同一文件中定义的 enum 会自动纳入生成的注册信息。

对于其他库拥有的类,请使用 @ForyStruct(target: ExternalType) 定义外部结构化序列化器

继承字段

普通 @ForyStruct() 会将具体父类和所应用 mixin 的字段展平到一个生成的子类 Schema 中。公共继承字段不要求父类添加注解。

私有字段、ignoreInheritedPrivateFields、跨库访问、构造函数、mixin 和 Schema 兼容性参见 Struct 继承

第 2 步:运行生成器

在包含 pubspec.yaml 的目录中运行:

dart run build_runner build

这会在源文件旁生成 .fory.dart 文件。每当新增或重命名带注解类型、修改继承层次存储,或修改公开边界或 ignoreInheritedPrivateFields 时,请重新运行此命令。

第 3 步:注册并使用

生成器会创建以文件命名的 Fory 模块类,并提供 register 函数。请在序列化前调用它:

final fory = Fory();
ModelsForyModule.register(fory, Address, id: 1);
ModelsForyModule.register(fory, User, id: 2);

也可以使用稳定名称代替数字 ID,这适合跨语言场景:

ModelsForyModule.register(
fory,
User,
name: 'example.User',
);

如何在 ID 和名称之间选择参见类型注册

Schema 演进:evolving

@ForyStruct() 默认使用 evolving: true,适合大多数应用。

  • evolving: true — Fory 存储足够的元数据,使将来新增或删除字段后,新旧代码仍能交换消息。只要应用或服务的不同版本可能同时运行,就应启用此设置。
  • evolving: false — 序列化更快、体积更小。仅当每个读取端和写入端始终使用相同 struct Schema 时才使用。
// evolving: true is the default, you can omit it
(evolving: true)
class Event {
Event();

String name = '';
}

使用可演进 struct 时,请在发布首个载荷前通过 @ForyField(id: ...) 分配稳定字段 ID;Schema 变化后,Fory 通过这些 ID 匹配字段。

纳入的继承字段和直接字段共享同一个 ID 命名空间。不要在同一个子类 Schema 纳入的字段之间复用 ID。

选择生成序列化还是自定义序列化

当其他包的类公开匹配的公共 getter 和安全的公共构造路径时,请使用外部结构化序列化器。当编码主体、字段名称、值或构造需要自定义逻辑时,请使用自定义序列化器

相关主题