增强插件系统:优化插件管理和动态插件实现

- 在插件管理器中引入 DynamicPlugin 结构体,支持动态加载和管理插件,提升插件的灵活性和可扩展性。
- 更新插件接口,添加插件名称、版本、描述、作者、类型和启用状态的获取和设置方法,增强插件信息的管理能力。
- 修改现有插件实现,确保兼容新的动态插件结构,提升插件的统一性和可维护性。
- 更新示例程序,展示如何使用新的动态插件功能,提升用户体验。

此更新提升了插件系统的灵活性和可扩展性,便于开发者更好地管理和使用插件功能。
This commit is contained in:
2025-03-14 07:12:05 +00:00
parent cc4c677553
commit 557059b2d2
11 changed files with 701 additions and 107 deletions

View File

@@ -3,7 +3,6 @@ package plugin
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
@@ -978,36 +977,445 @@ func (pm *PluginManager) loadPlugin(path string) error {
return fmt.Errorf("查找Plugin变量失败: %v", err)
}
// 类型断言
plugin, ok := symPlugin.(Plugin)
if !ok {
return errors.New("插件类型错误")
// 使用反射检查插件对象
pluginValue := reflect.ValueOf(symPlugin)
fmt.Printf("加载插件: %s, 类型: %s\n", path, pluginValue.Type())
// 查找基本字段或方法
var pluginName, pluginVersion, pluginAuthor, pluginDesc string
var pluginType PluginType = PluginTypeGeneral
var enabled = true
// 直接检查方法
// 尝试通过方法获取信息
nameFound := false
if nameMethod := pluginValue.MethodByName("Name"); nameMethod.IsValid() {
results := nameMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginName = results[0].String()
nameFound = true
}
}
if versionMethod := pluginValue.MethodByName("Version"); versionMethod.IsValid() {
results := versionMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginVersion = results[0].String()
}
}
if descMethod := pluginValue.MethodByName("Description"); descMethod.IsValid() {
results := descMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginDesc = results[0].String()
}
}
if authorMethod := pluginValue.MethodByName("Author"); authorMethod.IsValid() {
results := authorMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginAuthor = results[0].String()
}
}
if typeMethod := pluginValue.MethodByName("Type"); typeMethod.IsValid() {
results := typeMethod.Call(nil)
if len(results) > 0 {
// 尝试匹配插件类型
typeStr := fmt.Sprint(results[0].Interface())
switch typeStr {
case "storage":
pluginType = PluginTypeStorage
case "security":
pluginType = PluginTypeSecurity
case "network":
pluginType = PluginTypeNetwork
case "utils":
pluginType = PluginTypeUtils
case "hardware":
pluginType = PluginTypeHardware
case "ui":
pluginType = PluginTypeUI
}
}
}
// 直接检查字段(仅在方法不可用时)
if !nameFound && pluginValue.Kind() == reflect.Ptr && !pluginValue.IsNil() {
elemValue := pluginValue.Elem()
// 检查elemValue是否为结构体
if elemValue.Kind() == reflect.Struct {
// 检查是否有name字段
if nameField := elemValue.FieldByName("name"); nameField.IsValid() && nameField.Kind() == reflect.String {
pluginName = nameField.String()
}
// 检查是否有version字段
if versionField := elemValue.FieldByName("version"); versionField.IsValid() && versionField.Kind() == reflect.String {
pluginVersion = versionField.String()
}
// 检查是否有description字段
if descField := elemValue.FieldByName("description"); descField.IsValid() && descField.Kind() == reflect.String {
pluginDesc = descField.String()
}
// 检查是否有author字段
if authorField := elemValue.FieldByName("author"); authorField.IsValid() && authorField.Kind() == reflect.String {
pluginAuthor = authorField.String()
}
// 检查是否有pluginType字段
if typeField := elemValue.FieldByName("pluginType"); typeField.IsValid() {
// 转换为字符串并尝试匹配已知类型
typeStr := fmt.Sprint(typeField.Interface())
switch typeStr {
case "storage":
pluginType = PluginTypeStorage
case "security":
pluginType = PluginTypeSecurity
case "network":
pluginType = PluginTypeNetwork
case "utils":
pluginType = PluginTypeUtils
case "hardware":
pluginType = PluginTypeHardware
case "ui":
pluginType = PluginTypeUI
}
}
// 检查是否有enabled字段
if enabledField := elemValue.FieldByName("enabled"); enabledField.IsValid() && enabledField.Kind() == reflect.Bool {
enabled = enabledField.Bool()
}
}
}
// 如果名称仍为空,则使用文件名
if pluginName == "" {
// 从路径中提取文件名并去掉扩展名
fileName := filepath.Base(path)
pluginName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
}
fmt.Printf("创建适配器插件: 名称=%s, 版本=%s, 作者=%s, 类型=%s\n",
pluginName, pluginVersion, pluginAuthor, pluginType)
// 创建一个自定义插件结构体
customPlugin := &DynamicPlugin{
original: symPlugin,
name: pluginName,
version: pluginVersion,
description: pluginDesc,
author: pluginAuthor,
pluginType: pluginType,
enabled: enabled,
}
// 检查插件名称是否已存在
pm.mu.Lock()
defer pm.mu.Unlock()
if _, exists := pm.plugins[plugin.Name()]; exists {
return fmt.Errorf("插件 %s 已存在", plugin.Name())
if _, exists := pm.plugins[customPlugin.Name()]; exists {
return fmt.Errorf("插件 %s 已存在", customPlugin.Name())
}
// 设置插件启用状态
if config, exists := pm.configs[plugin.Name()]; exists {
if config, exists := pm.configs[customPlugin.Name()]; exists {
if enabled, ok := config["enabled"].(bool); ok {
plugin.SetEnabled(enabled)
} else {
plugin.SetEnabled(true) // 默认启用
customPlugin.enabled = enabled
}
} else {
plugin.SetEnabled(true) // 默认启用
}
// 注册插件
pm.registerPlugin(plugin)
pm.registerPlugin(customPlugin)
fmt.Printf("已成功注册插件: %s\n", customPlugin.Name())
return nil
}
// DynamicPlugin 完全动态的插件实现
type DynamicPlugin struct {
original interface{}
name string
version string
description string
author string
pluginType PluginType
enabled bool
}
// Name 返回插件名称
func (p *DynamicPlugin) Name() string {
return p.name
}
// Version 返回插件版本
func (p *DynamicPlugin) Version() string {
return p.version
}
// Description 返回插件描述
func (p *DynamicPlugin) Description() string {
return p.description
}
// Author 返回插件作者
func (p *DynamicPlugin) Author() string {
return p.author
}
// Type 返回插件类型
func (p *DynamicPlugin) Type() PluginType {
return p.pluginType
}
// IsEnabled 返回插件是否启用
func (p *DynamicPlugin) IsEnabled() bool {
return p.enabled
}
// SetEnabled 设置插件启用状态
func (p *DynamicPlugin) SetEnabled(enabled bool) {
p.enabled = enabled
// 尝试调用原始插件的SetEnabled方法
method := reflect.ValueOf(p.original).MethodByName("SetEnabled")
if method.IsValid() {
method.Call([]reflect.Value{reflect.ValueOf(enabled)})
}
}
// Init 初始化插件
func (p *DynamicPlugin) Init(ctx context.Context, config map[string]interface{}) error {
method := reflect.ValueOf(p.original).MethodByName("Init")
if !method.IsValid() {
return nil // 如果方法不存在,就不做任何事情
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 0:
// 无参数
case 1:
// 只有一个参数,可能是配置
args = append(args, reflect.ValueOf(config))
case 2:
// 两个参数,可能是上下文和配置
args = append(args, reflect.ValueOf(ctx), reflect.ValueOf(config))
default:
// 不支持更多参数
return fmt.Errorf("不支持的Init方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
return results[0].Interface().(error)
}
}
return nil
}
// Start 启动插件
func (p *DynamicPlugin) Start(ctx context.Context) error {
method := reflect.ValueOf(p.original).MethodByName("Start")
if !method.IsValid() {
return nil // 如果方法不存在,就不做任何事情
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 0:
// 无参数
case 1:
// 一个参数,可能是上下文
args = append(args, reflect.ValueOf(ctx))
default:
// 不支持更多参数
return fmt.Errorf("不支持的Start方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
return results[0].Interface().(error)
}
}
return nil
}
// Stop 停止插件
func (p *DynamicPlugin) Stop(ctx context.Context) error {
method := reflect.ValueOf(p.original).MethodByName("Stop")
if !method.IsValid() {
return nil // 如果方法不存在,就不做任何事情
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 0:
// 无参数
case 1:
// 一个参数,可能是上下文
args = append(args, reflect.ValueOf(ctx))
default:
// 不支持更多参数
return fmt.Errorf("不支持的Stop方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
return results[0].Interface().(error)
}
}
return nil
}
// Execute 执行插件功能
func (p *DynamicPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
method := reflect.ValueOf(p.original).MethodByName("Execute")
if !method.IsValid() {
return nil, fmt.Errorf("插件不支持Execute方法")
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 2:
// 两个参数可能是action和params
args = append(args, reflect.ValueOf(action), reflect.ValueOf(params))
case 3:
// 三个参数可能是ctx、action和params
args = append(args, reflect.ValueOf(ctx), reflect.ValueOf(action), reflect.ValueOf(params))
default:
// 不支持其他参数数量
return nil, fmt.Errorf("不支持的Execute方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
var result interface{}
var err error
switch len(results) {
case 1:
// 只有一个返回值,检查是否为错误
if results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
err = results[0].Interface().(error)
}
} else {
result = results[0].Interface()
}
case 2:
// 两个返回值,第一个是结果,第二个是错误
if !results[0].IsNil() {
result = results[0].Interface()
}
if results[1].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[1].IsNil() {
err = results[1].Interface().(error)
}
}
}
return result, err
}
// GetOperationInfo 获取操作的参数信息
func (p *DynamicPlugin) GetOperationInfo(operation string) (map[string]interface{}, error) {
method := reflect.ValueOf(p.original).MethodByName("GetOperationInfo")
if !method.IsValid() {
return map[string]interface{}{}, nil
}
results := method.Call([]reflect.Value{reflect.ValueOf(operation)})
var result map[string]interface{}
var err error
if len(results) > 0 && !results[0].IsNil() {
if m, ok := results[0].Interface().(map[string]interface{}); ok {
result = m
} else {
result = map[string]interface{}{}
}
} else {
result = map[string]interface{}{}
}
if len(results) > 1 && results[1].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[1].IsNil() {
err = results[1].Interface().(error)
}
}
return result, err
}
// GetAllOperations 获取所有操作及其参数信息
func (p *DynamicPlugin) GetAllOperations() map[string]map[string]interface{} {
method := reflect.ValueOf(p.original).MethodByName("GetAllOperations")
if !method.IsValid() {
return map[string]map[string]interface{}{}
}
results := method.Call(nil)
if len(results) > 0 && !results[0].IsNil() {
if m, ok := results[0].Interface().(map[string]map[string]interface{}); ok {
return m
}
}
return map[string]map[string]interface{}{}
}
// registerPlugin 注册插件到插件管理器
func (pm *PluginManager) registerPlugin(plugin Plugin) {
pluginType := plugin.Type()
@@ -1460,4 +1868,4 @@ func (pm *PluginManager) GetAllPluginsOperations() map[string]map[string]map[str
}
return result
}
}