代码生成
Fory 会在构建阶段为你的 Dart 类生成高性能序列化代码。你只需要给模型加注解、运行 build_runner,剩下的由 Fory 处理。
第一步:给模型加注解
为每个需要序列化的类添加 @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();
}
定义在同一文件中的枚举会自动包含到生成的注册代码里。
对于其他库拥有的类,请使用 @ForyStruct(target: ExternalType) 定义
外部结构化序列化器。
继承字段
普通的 @ForyStruct() 会把具体父类和所应用 mixin 中的字段展平到同一个
子类 Schema 中。父类中的 public 继承字段无需添加注解。
有关 private 字段、ignoreInheritedPrivateFields、跨库访问、构造函数、
mixin 和 Schema 兼容性的说明,请参阅结构体继承。
第二步:运行生成器
在包含 pubspec.yaml 的目录下运行:
dart run build_runner build
这会在源文件旁边生成一个 .fory.dart 文件。每当新增或重命名带注解的类型、
改变继承层次中的存储、改变暴露边界或修改 ignoreInheritedPrivateFields 时,
都需要重新运行此命令。
第三步:注册并使用
生成器会创建一个以源文件命名的 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:序列化速度更快,体积也更小。只有在所有读端和写端始终使用相同结构体 Schema 时才能使用。
// evolving: true 是默认值,可以省略
(evolving: true)
class Event {
Event();
String name = '';
}
使用 evolving 结构体时,也要在首次对外发送载荷之前通过 @ForyField(id: ...) 为字段分配稳定 ID,因为 Fory 会依赖这些 ID 在 Schema 变化后匹配字段。
被包含的继承字段和直接字段共享同一个 ID 命名空间。不要为同一子类 Schema 中的字段重复使用 ID。
选择生成序列化还是自定义序列化
如果另一个包中的类提供了匹配的 public getter 和安全的 public 构造路径, 请使用外部结构化序列化器。如果需要自定义编码数据体、 字段名、字段值或构造逻辑,请使用自定义序列化器。