33

插件开发指南

简介

本文档详细介绍Kknown框架中的插件开发流程,包括插件基类、注册机制、生命周期管理等核心概念。通过代码演示如何创建、注册和调用自定义插件,并说明插件与主框架的交互方式。

插件基础架构

PluginBase 基类

classDiagram
    class IPlugin {
        <<interface>>
        +Parent: BaseComponent
        +Info: PluginInfo
        +Config(Func<object, Task<Result>>): void
    }

    class PluginBase<T> {
        +Page: PluginPage
        +AutoPage: AutoPage
        +Parameter: T
        +Draggable: bool
        +Parent: BaseComponent
        +Info: PluginInfo
        +Config(Func<object, Task<Result>>): void
        +OnInitAsync(): Task
        +BuildRender(RenderTreeBuilder): void
        +BuildPlugin(RenderTreeBuilder): void
        +AddAction(string, string, Action): ActionInfo
        +SaveParameterAsync(T): Task<Result>
    }

    IPlugin <|-- PluginBase
    PluginBase *-- PluginInfo
    PluginBase o-- PluginPage

关键功能:

  1. 核心属性

    • Parameter: 插件配置参数
    • Info: 插件元信息
    • Page: 所属页面引用
  2. 生命周期方法

    • OnInitAsync: 初始化时自动添加删除操作
    • BuildRender: 构建插件渲染树
  3. 扩展方法

    • AddAction: 添加插件操作菜单
    • SaveParameterAsync: 保存插件配置

插件生命周期管理

初始化阶段

protected override async Task OnInitAsync()
{
    await base.OnInitAsync();
    AddAction("delete", "删除", OnDelete); // 自动添加删除操作
}

渲染阶段

protected override void BuildRender(RenderTreeBuilder builder)
{
    Parameter = Utils.FromJson<T>(Info?.Setting); // 反序列化配置
    builder.Component<PluginPanel>() // 构建插件容器
           .Set(c => c.Name, GetPluginName())
           .Set(c => c.Draggable, Draggable)
           .Set(c => c.Actions, Actions)
           .Set(c => c.ChildContent, BuildPlugin)
           .Build();
}

配置保存

protected Task<Result> SaveParameterAsync(T parameter)
{
    return Page.SaveParameterAsync(Info.Id, parameter); // 委托给页面保存
}

插件注册机制

PluginExtension 工具类

提供静态扩展方法管理插件:

flowchart TD
    A[GetPlugin] --> B{是否存在ID}
    B -->|是| C[按ID查找]
    B -->|否| D[返回第一个]
    
    E[GetPluginParameter] --> F[获取插件]
    F --> G[反序列化配置]
    
    H[AddPlugin] --> I{是否存在插件}
    I -->|否| J[创建新插件]
    I -->|是| K[更新配置]

关键方法:

  1. GetPluginParameter<T>: 获取插件配置
  2. AddPlugin<T>: 添加/更新插件配置
  3. BuildPlugin: 渲染插件组件

插件与主框架交互

服务接口

classDiagram
    class IPluginService {
        <<interface>>
        +GetTableActions(BaseTablePage): List<ActionInfo>
        +GetFormActions(BaseForm): List<ActionInfo>
        +ConfigTable(): void
        +AddTableColumn(): void
        +AddTableAction(): void
        +EditToolbar(KToolbar): void
    }

    class PluginService {
        +GetTableActions(BaseTablePage): List<ActionInfo>
        +GetFormActions(BaseForm): List<ActionInfo>
        +ConfigTable(): void
        +AddTableColumn(): void
        +AddTableAction(): void
        +EditToolbar(KToolbar): void
    }

    IPluginService <|-- PluginService

交互方式:

  1. 配置传递:通过PluginInfo.Setting序列化传递
  2. 事件委托:通过ActionInfo.OnClick绑定操作
  3. 服务调用:通过IPluginService扩展功能

实战示例

创建简单插件

// 1. 定义配置类
public class MyPluginConfig 
{
    public string Title { get; set; }
    public int Size { get; set; }
}

// 2. 继承PluginBase
[PagePlugin("我的插件")]
public class MyPlugin : PluginBase<MyPluginConfig>
{
    protected override void BuildPlugin(RenderTreeBuilder builder)
    {
        builder.Div($"标题: {Parameter.Title}, 大小: {Parameter.Size}");
    }
    
    public override void Config(Func<object, Task<Result>> onConfig)
    {
        // 显示配置对话框
        UI.ShowConfigDialog(Parameter, onConfig);
    }
}

注册插件

// 在页面初始化时添加插件
plugins.AddPlugin(new MyPluginConfig 
{
    Title = "示例",
    Size = 100
}, type: typeof(MyPlugin).FullName);

最佳实践

  1. 配置设计

    • 保持配置类简单可序列化
    • 提供合理的默认值
  2. 性能优化

    • 避免在BuildPlugin中执行复杂逻辑
    • 使用[Parameter]特性标记可变属性
  3. 错误处理

    • 处理配置反序列化失败情况
    • 验证插件参数有效性
  4. 扩展性

    • 通过AddAction暴露常用操作
    • 重写Config提供友好配置界面