编写服务
0.2 起,服务即插件:服务以插件形态编写与装载,在插件主体内通过 context.share() 提升到根作用域,对全框架可见。服务插件享有完整的插件生命周期:启用、禁用、依赖等待与级联。
不稳定的 API
Saukko Core 的内置服务与服务插件 API 尚处于开发阶段,可能会发生重大变化。
编写一个服务插件
typescript
import type { Context } from '@saukkojs/core';
// 通过对 ServiceRegistry 进行扩展,让消费方获得正确的类型推导。
declare module '@saukkojs/core' {
interface ServiceRegistry {
myService: MyService;
}
}
class MyService {
method() {
// ...
}
}
export const name = 'my-service';
export default async function (context: Context) {
await context.share('myService', new MyService());
}要点:
share(name, service)将服务登记进根作用域,所有权仍归插件的子作用域:随插件启用而启动、随禁用而摘除、随卸载而清理(详见 服务生命周期)。- 根作用域已有同名登记时
share抛错(不静默遮蔽),安装随之失败,可修正后重新安装。 - 缺省服务名为插件名:
context.share(new MyService())以my-service登记。显式不同名时(如上例),消费方需按服务名(myService)声明依赖,而非插件名。 - 服务插件经
plugin.files/ 插件依赖扫描装载;0.1 的service.files/service.scopes配置已废弃。
读取服务
消费方插件声明 inject 后经 context.get() 读取:
typescript
export const inject = ['myService'];
export const name = 'my-plugin';
export default function (context: Context) {
context.get('myService')?.method();
}未声明 inject 的服务也可沿作用域父链读取(全量可读);inject 的价值在于依赖编排:依赖未就绪时挂起等待、启动顺序保证、服务消失时的级联停止与恢复(见 依赖与诊断)。
内置服务
app: 应用服务,用于管理框架的生命周期。logger: 日志服务,用于记录框架的日志。config: 配置服务,用于管理框架的配置。storage: 存储服务,用于管理框架的持久化数据。database(WIP): 数据库服务,用于管理框架的数据库连接。plugin: 插件服务,用于管理框架的插件。
关于 app 服务
为了让框架更加灵活,我们将 app 也设计为一个服务。这使得用户可以更加方便地管理框架的生命周期。
底层装配:register 与 provide
内置服务的装配(injectionProvider)仍使用作用域底层 API:
scope.register(name, target):惰性注册,首次get时实例化,构造依赖按静态inject沿父链解析;scope.provide(name, service):立即登记并纳入作用域生命周期管理,覆盖同名服务时触发联动重启。
这两个 API 面向框架装配与测试场景。用户服务请优先使用服务插件 + share,以获得启用/禁用开关、依赖等待与级联恢复语义。
同时,我们会在下个版本中对内置服务与装配方法做出调整。