插件包是 plugins/ 下的一个目录;目录名就是插件名,里面必须有 manifest.json。框架在载入之前读清单,并拒绝不合格的包。
plugins/ hello-csharp/ manifest.json main.cs hello-csharp.conf{ "name": "hello-csharp", "entry": "main.cs", "type": "hosihikari", "version": "1.0.0", "dependencies": [ { "name": "hosihikari" }, { "name": "hosihikari-csharp" } ], "extraInfo": { "api": "2", "format_version": "1", "provider": "csharp" }}| 字段 | 说明 |
|---|---|
name |
插件名,必须等于目录名。 |
entry |
包内相对路径;绝对路径与 .. 出界。 |
type |
路由键,hosihikari。 |
version |
插件自己的版本字符串。 |
dependencies |
依赖的插件名;依赖图决定装载顺序。 |
extraInfo.api |
契约主版本,当前 2。 |
extraInfo.format_version |
清单 schema 版本,当前 1。 |
extraInfo.provider |
处理这个包的 Provider。assembly 是核心内置入口;csharp、fsharp 是一等 Provider;rpc 是例外一等 Provider。 |
extraInfo.command |
仅 rpc:编码成字符串的 JSON 数组。 |
依赖按名字排序,没有版本约束;框架自身是 hosihikari。一等 Provider 声明 hosihikari-csharp 或 hosihikari-fsharp;例外一等 Provider 声明 hosihikari-rpc。Provider 包先于依赖它的包装载。预编译程序集走核心内置入口,不需要 Provider 包。
Provider 与入口
Section titled “Provider 与入口”官方 Provider 分两类:一等 Provider 把源码 AOT 为 IL;RpcProvider 是例外一等 Provider,跨进程桥。预编译程序集走核心内置入口。
provider |
entry |
装载方式 |
|---|---|---|
assembly |
.dll |
核心内置:直接装载预编译 IL 程序集;程序集上恰好一个 [assembly: EntryPoint<T>]。 |
csharp |
.cs |
一等 Provider:Roslyn 装载时把 .cs AOT 为 IL,产物进 collectible ALC。 |
fsharp |
.fsx |
一等 Provider:FSharp.Compiler.Service 装载时把 .fsx AOT 为 IL。 |
rpc |
入口文件 | 例外一等 Provider:由 command 启动子进程,行分隔 JSON-RPC 2.0 over stdio。 |
一等 Provider 与预编译程序集插件的入口类型必须实现 IPlugin 且有无参构造;EntryPoint<T> 的泛型约束在编译期保证这两条。文件缺失、程序集里的入口声明数量不对等,由 Provider 报告。
框架在构造插件之前拒绝:
name与目录名不一致;entry为空、绝对路径或越出包目录;type不是hosihikari;api不是2;format_version不是1;- 清单不是合法 JSON。
这些检查发生在包进入生命周期之前,日志里会给出可读的原因。
- 包内默认:
plugins/<name>/<name>.conf,随包更新。 - 服务端覆盖:
config/hosihikari/<name>.conf,优先于包内。 - 环境变量:覆盖同名键(
greeting对应GREETING)。 - 运行期数据:
data/hosihikari/<name>/,由框架创建并交给插件。
配置是 HOCON。分层走框架的 provider 链,HOCON 的 include 在这条路径上不生效。
OnLoad → OnEnable → OnDisable → OnUnload。
OnLoad时依赖已就绪;服务器未必已就绪。OnEnable允许后打开作用域闸门;拒绝时插件留在册、保持未启用。OnDisable之前框架关闭闸门,不再投递事件与定时器;拒绝时闸门重开。- 卸载经停用;
OnUnload释放插件持有的东西。 - 钩子抛异常是故障:宿主卸载插件并通知载体。
回调闸门只管框架投递的事件与定时器。插件自有的线程、服务登记与直接引用要自己在 OnUnload 里收尾。
Provider 包装上后不能运行期卸载;禁用或升级需重启服务端。
