Lifecycle de Extensions¶
sequenceDiagram
participant K as Kernel
participant E as Extension
participant C as Container
K->>E: register()
E->>C: bind services, definitions, item types
K->>E: boot()
E->>C: resolve services, register hooks/routes
K->>C: compile()
C->>C: validate cycles, freeze, cache routes
Fases¶
| Fase | Permitido | Proibido | Violação |
|---|---|---|---|
register() |
Bind services no container. Declarar typed definitions (caches, capabilities, events, file areas, messages, hooks, services). Publicar item types. | Resolver do container. Dispatch de signals ou commands. Chamar do_action() ou apply_filters(). |
middag_lifecycle_violation_exception |
boot() |
Resolver services do container. Registrar subscribers, hooks, shortcodes, controllers. Chamar do_action(). Configurar rotas. |
Criar novos bindings no container. | middag_lifecycle_violation_exception |
compile() |
Somente leitura. Kernel válida ciclos de dependência, congela o container, faz cache das rotas compiladas. | Qualquer operação de escrita no container. | middag_lifecycle_violation_exception |
Ordenação de dependências¶
Extensions declaram dependências via REQUIRES na classe da extension. O kernel ordena topologicamente antes de invocar register() e boot().
Se extension B depende de extension A:
register()de A executa antes deregister()de Bboot()de A executa antes deboot()de B
Cascade disable¶
Quando uma dependência obrigatória está ausente ou desativada:
- Todas as extensions que dependem da extension ausente são desativadas em cascata
- Um warning e logado para cada extension desativada
- As demais extensions prosseguem normalmente
Discovery¶
Extensions são auto-descobertas por sufixo de arquivo. O kernel escaneia classes/extensions/ por arquivos {slug}_extension.php. Cada arquivo contém uma classe implementando extension_interface.
Não é necessário registro manual. Colocar o arquivo no diretório de extensions é suficiente.
Violações¶
Qualquer operação que viole as restrições de fase lança middag_lifecycle_violation_exception (HTTP 500, @internal). Esta exceção não é capturável por código de extension e interrompe o lifecycle da extension.
| Código | Fase | Resultado |
|---|---|---|
$container->get(service::class) |
register() |
Exceção: resolve não permitido em register |
$container->bind(service::class, ...) |
boot() |
Exceção: novos bindings não permitidos em boot |
$container->bind(...) |
compile() |
Exceção: container congelado |