Plugin and Service Registry
Relevant source files
The following files were used as context for generating this wiki page:
The Plugin and Service Registry (implemented primarily as FlextRegistry) serves as the central orchestration point for managing CQRS handlers, service components, and extensible plugins within the FLEXT-Core framework. It acts as a bridge between high-level service definitions and the underlying dependency injection container, ensuring that handlers and plugins are correctly bound, validated, and discoverable by the system's dispatcher.
This system provides a unified interface for registering synchronous and asynchronous handlers, managing plugin lifecycles across different scopes (Instance vs. Class), and generating registration summaries for batch operations. It is designed to work in tandem with the FlextDispatcher to facilitate clean architecture patterns such as Command-Query Responsibility Segregation (CQRS).
Sources: src/flext_core/_registry_parts/flextregistry_part_02.py:1-15, src/flext_core/_protocols/registry.py:27-35, examples/ex_12_registry_flow.py:30-40
Core Architecture and Components
The registry architecture is built on a tiered implementation that separates state management from registration logic. The FlextRegistry class uses an immutable state model to track registered keys, ensuring thread-safe updates to the registry metadata.
System Components
The following diagram illustrates the relationship between the Registry, the Container, and the Dispatcher.
The relationship between the Registry facade and the internal storage mechanisms.
Sources: src/flext_core/_registry_parts/flextregistry_part_01.py, src/flext_core/_registry_parts/flextregistry_part_02.py:84-106
Registration Scopes
The registry supports two primary registration scopes, allowing for flexible service lifetimes:
| Scope | Description | Persistence |
|---|---|---|
INSTANCE | Bound to a specific instance of the registry. | Lost when registry instance is destroyed. |
CLASS | Shared across all instances of the registry class. | Persists in class-level storage. |
Sources: src/flext_core/_registry_parts/flextregistry_part_02.py:108-112, examples/ex_12_registry_plugins.py:75-80
Handler Registration Workflow
Handlers are the core units of execution in the CQRS pattern. The registry provides multiple methods for binding these handlers to the dispatcher.
Registration Methods
register_handler: Registers a single handler instance or callable.register_handlers: Facilitates batch registration of multiple handlers, returning aRegistrySummarycontaining success and error details.register_bindings: Maps specific message types or keys to handlers.
Sources: src/flext_core/_protocols/registry.py:70-85, examples/ex_12_registry_flow.py:55-65
Handler Normalization Process
When a handler or plugin is registered, the registry performs "narrowing" to ensure the value conforms to the container's binding contract.
The internal narrowing process for registry values.
Sources: src/flext_core/_registry_parts/flextregistry_part_02.py:25-45
Plugin Management
Plugins represent extensible components that may require validation during registration. Unlike standard handlers, plugins are often categorized and can be queried or listed by their category.
Plugin Operations
The registry implements a complete CRUD-like interface for plugins:
register_plugin: Allows adding a plugin with an optionalvalidatecallable. This callable must return aResult[bool]to confirm the plugin is valid for its intended purpose.fetch_plugin: Retrieves a plugin based on its category and name. It automatically checks the specified scope (Instance or Class).list_plugins: Returns a sequence of all registered plugin names within a specific category.unregister_plugin: Removes a plugin from the registry state and container.
Sources: src/flext_core/_protocols/registry.py:90-128, src/flext_core/_registry_parts/flextregistry_part_02.py:108-142
Validation Logic
The registration of a plugin can be gated by a validation function. If the validation fails (returns a failure result) or raises an exception, the registry rejects the registration.
# Example of validated plugin registration
plugin_validated = registry.register_plugin(
category="transport",
name="grpc",
plugin=my_plugin_instance,
validate=lambda pval: r[bool].ok(bool(pval)),
)
Sources: examples/ex_12_registry_plugins.py:44-55
Batch Operations and Summaries
When performing bulk registrations via register_handlers or register_bindings, the system utilizes the RegistrySummary model to provide feedback.
| Field | Type | Description |
|---|---|---|
registered | list[RegistrationDetails] | List of successfully registered handler metadata. |
errors | list[str] | List of error messages encountered during the batch. |
success | bool (property) | True if no errors are present in the summary. |
Sources: src/flext_core/_registry_parts/flextregistry_part_02.py:155-177, examples/ex_12_registry_flow.py:90-110
Conclusion
The Plugin and Service Registry is a robust module that centralizes the management of executable components in FLEXT-Core. By enforcing strict narrowing of values and supporting scoped registration, it provides a reliable foundation for building extensible, dispatcher-driven applications. Its integration with the dependency injection container ensures that all registered services remain lifecycle-aware and easily resolvable throughout the application runtime.