registerExtensions method
Registers a body callback that wires additional bridge state
(e.g. registerRelaxers(), registerD4rtRuntimeExtensions(),
registerD4rtInterfaceProxyOverrides()) after the main
registerBridgedClass/registerBridgedEnum/etc. registrations
for packageName have happened.
The body is not run immediately — the runner queues it and runs
every queued body in registration order when finalizeBridges is
called (or implicitly on the first execute*/executeBundle* call
that follows). This replaces the comment-driven "must run AFTER
bridges" rule (formerly enforced by code ordering inside
FlutterD4rt._registerBridges) with an enforced mechanism: bridge
packages declare their wiring up front, and the runner controls
when it runs.
Idempotent on package name: a second call with the same
packageName overwrites the previous body — the contract is one
extension callback per bridge package. The body itself must
internally tolerate being run more than once if the embedder
constructs multiple D4rtRunner instances in the same process,
since the D4 / BridgedClass registries it touches are static.
(Step 5 made all the per-key D4 registries idempotent on factory
identity, so this contract is satisfied for the standard
register* calls.)
Throws StateError if finalizeBridges has already run on this runner — adding extensions after finalization is a misuse.
Implementation
void registerExtensions(String packageName, void Function() body) {
if (_bridgesFinalized) {
throw StateError(
'Cannot registerExtensions("$packageName"): finalizeBridges() has '
'already been called on this D4rtRunner. Register all extensions '
'before the first execute*/executeBundle* call (or call '
'finalizeBridges() explicitly after the last registerExtensions).',
);
}
_extensionCallbacks[packageName] = body;
}