依赖与诊断
插件通过 inject 声明依赖。inject 中的一个名字有两种语义,按解析结果决定:
typescript
export const inject = ['storage', 'other-plugin'];- 命中作用域中登记的服务:服务依赖。实例沿作用域父链经
context.get()读取。 - 命中已安装的插件:插件依赖。仅约束启动顺序——被依赖方先启动、后停止——不做实例注入。
- 都不命中:缺失依赖,插件进入"等待依赖"状态。
等待语义
缺失依赖不是错误,而是一种可恢复的状态:
- install 时依赖未就绪:插件主体挂起(不执行),
plugin list显示waiting及等待的依赖清单; - 依赖补齐(服务经
provide/share登记,或被依赖的插件安装):挂起的主体自动按拓扑序执行; - enable 时依赖未就绪:不拒绝——插件被标记为"期望启用",依赖就绪且主体执行完成后自动触发
onStart; - 以上自动迁移全程可等待:触发依赖补齐的调用返回时,迁移已完成。
依赖判定是级联的:若插件依赖另一个等待中的插件,同样进入等待。
依赖消失与级联
依赖由就绪变为消失时(服务插件被 disable / uninstall,或被依赖的插件被卸载):
- 依赖它的已启用插件(含传递依赖)按依赖拓扑逆序自动停止;
- 这些插件保留"期望启用"标记,记录为等待依赖——与用户主动禁用区分开;
- 依赖恢复后按拓扑正序自动重启;用户主动禁用的插件不受影响。
依赖诊断
诊断将插件分为三类:依赖就绪(进入启动序列)、等待依赖(报告等待原因,就绪后自动迁移)、循环依赖(硬错误,无法通过等待解决,排除出启动序列并给出循环路径)。
诊断发生在两个时机:
- 框架启动:就绪的插件按拓扑序启用,等待中的插件标记为期望启用,循环依赖的插件报错且不启动;
- 动态启用:
saukko plugin enable每次都会重新诊断——循环依赖拒绝启用;缺失依赖按等待语义处理,响应中说明正在等待的依赖。
启动与停止顺序
框架按依赖拓扑排序启动插件:被依赖方先启动。停止按拓扑的逆序:依赖方先停止。这与作用域"先子后父"的销毁顺序一致。
服务替换与联动重启
通过 provide 覆盖根作用域中的同名服务时,框架会联动重启受影响的插件:
- 旧服务先停止(其生命周期钩子被摘除,不会残留);
- 新服务启动并就绪;
- 受影响集合 = 直接依赖该服务的插件 + 传递依赖这些插件的插件;
- 受影响插件按依赖拓扑逆序停止、正序重启:同一 Context 上重新触发
onStop/onStart,全程可等待。
未被波及的插件保持运行;当时处于禁用状态的插件不会被重启;重启失败的插件保持未启用,可手动重试。联动失败会汇总抛回发起 provide 的调用方。