跳到主要内容
版本:0.4.x(Latest)

基本介绍

提供方声明覆盖源码插件对SPI能力提供方工厂的注册。SPIService Provider Interface)模式将能力契约与能力实现分离,宿主定义领域能力的公开接口,提供方插件负责实现具体业务逻辑。动态插件不能注册SPI工厂,只能消费已发布的SPI能力。

能力阶段:声明期

类型支持:仅源码插件

能力设计

SPI架构

支持的提供方类型

提供方工厂接口能力包官方插件
Tenanttenantspi.ProviderFactorytenantcaplinapro-tenant-core
Orgorgspi.ProviderFactoryorgcaplinapro-org-core
AI Textaitext.ProviderFactoryaicaplinapro-ai-core

ProviderEnv注入

宿主通过ProviderEnv向提供方注入运行期上下文:

注入项说明
插件身份当前提供方插件的ID,用于审计和隔离
请求上下文当前请求的租户、用户等业务上下文
辅助能力提供方实现所需的宿主能力

提供方状态检查

宿主通过Plugins().State().IsProviderEnabled()判断提供方是否可用:

检查方法语义适用场景
IsEnabled插件的业务入口对当前租户是否可见菜单过滤、路由可见性
IsProviderEnabled插件是否平台启用且可承接提供方调用AIOrgTenant能力调用前检查

提供方检查确保即使业务入口被租户级禁用,平台级能力仍可正常服务。

延迟构造

宿主只在能力首次被消费时构造提供方实例,避免启动阶段强依赖可选插件。

安全降级

没有可用提供方时,能力返回空结果或不可用状态,而非nil或错误。

接口定义

源码插件接口

源码插件通过Providers()注册提供方工厂:

方法工厂接口说明
ProvideTenanttenantspi.ProviderFactory注册租户能力提供方
ProvideOrgorgspi.ProviderFactory注册组织能力提供方
ProvideAITextaitext.ProviderFactory注册AI文本能力提供方

每个工厂是一个构造函数,接收ProviderEnv参数并返回提供方实例。

动态插件接口

动态插件不能注册SPI工厂。动态插件通过以下方式与SPI能力交互:

交互方式说明
消费SPI能力通过hostServices声明调用已发布的SPI能力方法
检查提供方状态通过plugins.provider_enabled.check动态方法判断提供方是否可用
状态查询通过capability.availablecapability.status动态方法查询能力可用性

能力使用

源码插件使用

源码插件在init()中注册提供方工厂:

func init() {
plugin := pluginhost.NewDeclarations("my-author-my-org-provider")
if err := plugin.Providers().ProvideOrg(orgProviderFactory); err != nil {
panic(err)
}

if err := pluginhost.RegisterSourcePlugin(plugin); err != nil {
panic(err)
}
}

// 工厂函数
func orgProviderFactory(ctx context.Context, env orgspi.ProviderEnv) (orgspi.Provider, error) {
return &myOrgProvider{env: env}, nil
}

实现提供方契约:

type myOrgProvider struct {
env orgspi.ProviderEnv
}

func (p *myOrgProvider) ListUserDeptAssignments(ctx context.Context, userIDs []int) (map[int]*orgcap.UserDeptAssignment, error) {
// 查询提供方自己的组织数据
return queryDeptAssignments(ctx, userIDs)
}

func (p *myOrgProvider) GetUserDeptInfo(ctx context.Context, userID int) (int, string, error) {
// 实现部门信息查询
return queryDeptInfo(ctx, userID)
}

注册AI文本提供方:

func (p *myAIPlugin) ProvideAIText(factory aitext.ProviderFactory) error {
p.aiTextProvider = factory
return nil
}

func aiTextProviderFactory(env aitext.ProviderEnv) aitext.Provider {
return &myAITextProvider{env: env}
}

动态插件使用

动态插件通过hostServices声明消费SPI能力:

hostServices:
- service: ai
methods:
- text.generate
- service: org
methods:
- users.dept_name.get
- service: tenant
methods:
- tenants.current

检查提供方状态:

// 通过 plugins.provider_enabled.check 检查
enabled := pluginbridge.Default().Plugins().State().IsProviderEnabled(ctx, "linapro-ai-core")
if enabled {
// 使用AI能力
}

设计约束

  • 提供方声明仅限源码插件。 动态插件不能注册SPI工厂,因为提供方需要实现Go接口并运行在宿主进程中。
  • 每个能力只能有一个提供方。 同一能力重复注册提供方会返回错误。
  • 延迟构造避免强依赖。 宿主只在能力首次被消费时构造提供方实例。
  • 安全降级保证稳定性。 没有可用提供方时,能力返回空结果而非错误。
  • 提供方状态独立于业务入口。 插件业务入口可能对租户不可见,但仍可作为平台能力提供方可用。
  • ProviderEnv是注入通道。 宿主通过ProviderEnv向提供方注入上下文和辅助能力,提供方不应自行获取。

相关文档