PluginRegistrationAPI
Reference
The PluginRegistrationAPI
is the primary interface provided to plugins for interacting with Castlecraft Architect's core component registration and path resolution systems. An instance of this API is passed to your plugin's registration function by the PluginManager
.
Overview
The API allows plugins to:
- Register new component types.
- Override existing component types (both core and those from other plugins).
- Provide custom path resolution logic for component types.
Initialization
You do not need to initialize PluginRegistrationAPI
yourself. An instance is created by the PluginManager
and provided to your plugin's registration function.
It is initialized with instances of ComponentRegistryService
and ComponentLocatorService
:
# Simplified internal representation
class PluginRegistrationAPI:
def __init__(
self,
registry_service: "ComponentRegistryService",
locator_service: "ComponentLocatorService",
):
self._registry = registry_service
self._locator = locator_service
# ... methods ...
Methods
register_component()
This is the main method used to register or override a component type.
def register_component(
self,
component_type_key: str,
meta: "ComponentMeta",
handler_class: Type["ComponentTypeHandler"],
path_resolver: Optional[Callable[[str, Dict[str, Any]], Optional[str]]] = None,
is_override: bool = False,
plugin_name: str = "unknown_plugin",
):
Parameters:
component_type_key
(str
): A unique string identifier for the component type (e.g.,"custom_widget"
,"dto"
). This key is case-insensitive internally.meta
(ComponentMeta
): A dictionary containing metadata for the component. Refer to theComponentMeta
type definition (typically found inComponentRegistryService
) for the expected structure. Key fields includecomponent_slug
,file_name_template
,required_context
,class_suffix
, anddescription
.handler_class
(Type[ComponentTypeHandler]
): The class responsible for handling this component type. It must be a subclass ofComponentTypeHandler
. This class defines logic for code generation, schema validation, etc.path_resolver
(Optional[Callable[[str, Dict[str, Any]], Optional[str]]]
, default:None
): An optional callable function that determines the file path for instances of this component type.- Signature:
resolver(component_name: str, context_kwargs: Dict[str, Any]) -> Optional[str]
- If
None
, and the component is new, path resolution will fall back toPROJECT_STRUCTURE_DEFINITION
if a match is found. If overriding, andNone
is provided, an existing custom resolver for thiscomponent_type_key
will not be removed or changed unless the original registration also had no resolver. To explicitly remove/reset a custom resolver during an override, you'd need a mechanism inComponentLocatorService
(not currently implemented via this API directly).
- Signature:
is_override
(bool
, default:False
):- If
True
, this registration will override any existing component definition (metadata, handler, and custom path resolver ifpath_resolver
is provided) for the givencomponent_type_key
. A log message will indicate the override. - If
False
(default), and a component withcomponent_type_key
already exists, this registration attempt will be skipped, and an error will be logged.
- If
plugin_name
(str
): The name of the plugin performing the registration. This is automatically supplied by thePluginManager
when it calls your plugin's registration function.
Usage Example (within your plugin's registration function):
# In your plugin's registration function, which now also receives the container:
# def register_my_plugin_components(
# api: "PluginRegistrationAPI",
# container: "punq.Container", # The DI container
# plugin_name: str
# ):
# api.register_component(
# component_type_key="my_new_component",
# meta=MY_NEW_COMPONENT_META,
# handler_class=MyNewComponentHandler,
# path_resolver=my_new_component_path_resolver,
# plugin_name=plugin_name
# )
# api.register_component(
# component_type_key="core_component_to_override", # e.g., "dto"
# meta=OVERRIDDEN_CORE_COMPONENT_META,
# handler_class=MyOverriddenCoreComponentHandler,
# path_resolver=my_overridden_path_resolver,
# is_override=True,
# plugin_name=plugin_name
# )
This API provides a focused way for plugins to integrate their custom components and behaviors into the Architect framework.