Type Registration
Fory needs to know which class corresponds to which type in a serialized message. You do this by registering each class before you serialize or deserialize it.
Choosing a Registration Strategy
Fory offers two strategies. Pick one and use it consistently across every language that reads or writes the type.
Strategy 1: Numeric ID
Compact and fast. Good when a small team can coordinate IDs across services.
ModelsForyModule.register(fory, User, id: 100);
The same number must be used in every other language:
// Java side
fory.register(User.class, 100);
Strategy 2: Name
More self-describing. Good when multiple teams or packages define types independently and numeric ID coordination is impractical.
ModelsForyModule.register(
fory,
User,
name: 'example.User',
);
Every peer that reads or writes this type must use the same name. Use . inside name
to add a namespace prefix.
Do not mix strategies for the same type. If one side uses a numeric ID and the other uses a name, deserialization will fail.
Registering Generated Types
Call the generated register function from the .fory.dart file. It installs all the serializer metadata for you:
UserModelsForyModule.register(fory, User, id: 100);
For an ordinary inherited type, register the concrete annotated child. Its generated serializer already owns the complete flattened child schema; Fory does not require separate registration of a superclass or mixin merely because it contributes fields.
Register an independently annotated concrete parent only when values whose
actual type is exactly that parent are also serialized. A provider-only
@ForyStruct(exposePrivateFields: true) boundary supplies generated field
access and has no registration entry of its own. See
Struct Inheritance for boundary and child-schema options.
External structural serializers use the same generated registration API. Pass the external target type:
ExternalSerializersForyModule.register(
fory,
third_party.User,
id: 100,
);
See External-Type Serialization for the declaration.
Registering a Custom Serializer
Pass a serializer instance directly when a type needs custom wire or construction logic:
fory.registerSerializer(
ExternalType,
const ExternalTypeSerializer(),
name: 'example.ExternalType',
);
See Custom Serializers for how to implement a serializer.
Rules to Follow
- Register before the first
serialize,serializeTo,serializeBuiltin,serializeBuiltinTo,deserialize, ordeserializeFromcall. That first root operation permanently closes registration for theForyinstance, even if the operation fails; create a new instance when a different registry is required. - Register every class that can appear in a message, not only the root type.
- Do not register generated private-field access companions; register only concrete serialized types.
- Keep IDs (or names) stable once payloads are persisted or exchanged across services. Changing them will break deserialization of old messages.
- Do not mix a numeric ID on one side with a name on the other for the same type.
Xlang Requirements
The same numeric ID or name must be used in every peer that reads or writes the type. See Cross-Language Interoperability for examples.