From 7f2a49ba3c80b7e897dc19d405a69c97f25fc78f Mon Sep 17 00:00:00 2001
From: "meilin.huang" <954537473@qq.com>
Date: Fri, 13 Dec 2024 12:15:24 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9C=BA=E5=99=A8=E6=96=87=E4=BB=B6?=
=?UTF-8?q?=E5=86=85=E5=AE=B9=E5=86=99=E5=85=A5=E5=AF=BC=E8=87=B4=E5=86=85?=
=?UTF-8?q?=E5=AE=B9=E6=B8=85=E7=A9=BA=E3=80=81feat:=20ioc=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E6=A0=B9=E6=8D=AE=E7=B1=BB=E5=9E=8B=E6=B3=A8=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +-
README_EN.md | 2 +-
frontend/package.json | 2 +-
frontend/src/components/SearchForm/index.vue | 6 +-
.../components/terminal/TerminalSearch.vue | 4 +-
frontend/src/i18n/en/common.ts | 1 +
frontend/src/i18n/zh-cn/common.ts | 1 +
frontend/src/views/ops/db/db.ts | 6 +-
server/go.mod | 4 +-
server/internal/file/application/file.go | 4 -
server/internal/flow/application/procdef.go | 5 -
server/internal/flow/application/procinst.go | 5 -
.../internal/machine/application/machine.go | 5 -
.../machine/application/machine_cmd_conf.go | 5 -
.../machine/application/machine_cronjob.go | 5 -
.../machine/application/machine_file.go | 7 +-
.../machine/application/machine_script.go | 5 -
.../machine/application/machine_term_op.go | 5 -
server/internal/mongo/application/mongo.go | 5 -
server/internal/redis/application/redis.go | 5 -
server/internal/sys/application/account.go | 5 -
server/internal/sys/application/config.go | 4 -
server/internal/sys/application/resource.go | 5 -
server/internal/sys/application/role.go | 4 -
.../tag/application/resouce_auth_cert.go | 5 -
.../tag/application/resource_op_log.go | 5 -
server/internal/tag/application/tag_tree.go | 5 -
.../tag/application/tag_tree_relate.go | 5 -
server/pkg/base/app.go | 2 +-
server/pkg/ioc/component.go | 4 +
server/pkg/ioc/ioc.go | 146 +++++++++++++-----
31 files changed, 135 insertions(+), 139 deletions(-)
diff --git a/README.md b/README.md
index 34131b08..ec607921 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# 🌈mayfly-go
+# 🌈Dromara mayfly-go
English |
diff --git a/README_EN.md b/README_EN.md
index 2df6d8ae..2597267c 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,4 +1,4 @@
-# 🌈mayfly-go
+# 🌈Dromara mayfly-go
中文介绍 |
diff --git a/frontend/package.json b/frontend/package.json
index 3d23e514..ab503a53 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -24,7 +24,7 @@
"jsencrypt": "^3.3.2",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
- "monaco-editor": "^0.52.0",
+ "monaco-editor": "^0.52.2",
"monaco-sql-languages": "^0.12.2",
"monaco-themes": "^0.4.4",
"nprogress": "^0.2.0",
diff --git a/frontend/src/components/SearchForm/index.vue b/frontend/src/components/SearchForm/index.vue
index 6c7984d3..4550152e 100644
--- a/frontend/src/components/SearchForm/index.vue
+++ b/frontend/src/components/SearchForm/index.vue
@@ -6,7 +6,7 @@
- {{ `${item?.label}` }}
+ {{ `${$t(item?.label)}` }}
@@ -21,8 +21,8 @@
-
搜索
-
重置
+
{{ $t('common.search') }}
+
{{ $t('common.reset') }}
{{ collapsed ? '展开' : '合并' }}
diff --git a/frontend/src/components/terminal/TerminalSearch.vue b/frontend/src/components/terminal/TerminalSearch.vue
index 9f25c6b2..ca97bf0d 100644
--- a/frontend/src/components/terminal/TerminalSearch.vue
+++ b/frontend/src/components/terminal/TerminalSearch.vue
@@ -31,10 +31,10 @@
- {{ $t('components.terminal.previous') }}}}
+ {{ $t('components.terminal.previous') }}
- {{ $t('components.terminal.next') }}}}
+ {{ $t('components.terminal.next') }}
{{ $t('components.terminal.close') }}
diff --git a/frontend/src/i18n/en/common.ts b/frontend/src/i18n/en/common.ts
index dfcfa202..9fd6f9c4 100644
--- a/frontend/src/i18n/en/common.ts
+++ b/frontend/src/i18n/en/common.ts
@@ -45,6 +45,7 @@ export default {
previousStep: 'Previous Step',
nextStep: 'Next Step',
copy: 'Copy',
+ search: 'Search',
pleaseInput: 'Please enter {label}',
pleaseSelect: 'Please select {label}',
formValidationError: 'Please check the form',
diff --git a/frontend/src/i18n/zh-cn/common.ts b/frontend/src/i18n/zh-cn/common.ts
index 76384b25..f0c7dbd5 100644
--- a/frontend/src/i18n/zh-cn/common.ts
+++ b/frontend/src/i18n/zh-cn/common.ts
@@ -45,6 +45,7 @@ export default {
previousStep: '上一步',
nextStep: '下一步',
copy: '复制',
+ search: '搜索',
pleaseInput: '请输入{label}',
pleaseSelect: '请选择{label}',
formValidationError: '信息填写有误,请检查',
diff --git a/frontend/src/views/ops/db/db.ts b/frontend/src/views/ops/db/db.ts
index 642add48..6750b5b0 100644
--- a/frontend/src/views/ops/db/db.ts
+++ b/frontend/src/views/ops/db/db.ts
@@ -123,7 +123,7 @@ export class DbInst {
},
kind: monaco.languages.CompletionItemKind.File,
detail: tableComment,
- insertText: dbDialect.quoteIdentifier(tableName) + ' ',
+ insertText: dbDialect.quoteIdentifier(tableName),
range,
sortText: 300 + index + '',
});
@@ -147,7 +147,7 @@ export class DbInst {
},
kind: monaco.languages.CompletionItemKind.Property,
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
- insertText: dbDialect.quoteIdentifier(fieldName) + ' ', // create_time
+ insertText: dbDialect.quoteIdentifier(fieldName), // create_time
range,
sortText: 100 + index + '', // 使用表字段声明顺序排序,排序需为字符串类型
});
@@ -819,7 +819,7 @@ export function registerDbCompletionItemProvider(dbId: number, db: string, dbs:
},
kind: monaco.languages.CompletionItemKind.File,
detail: tableComment,
- insertText: dbDialect.quoteIdentifier(tableName) + ' ',
+ insertText: dbDialect.quoteIdentifier(tableName),
range,
sortText: 300 + index + '',
});
diff --git a/server/go.mod b/server/go.mod
index 41241a25..496bfa66 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -32,8 +32,8 @@ require (
github.com/tidwall/gjson v1.18.0
github.com/veops/go-ansiterm v0.0.5
go.mongodb.org/mongo-driver v1.16.0 // mongo
- golang.org/x/crypto v0.30.0 // ssh
- golang.org/x/oauth2 v0.23.0
+ golang.org/x/crypto v0.31.0 // ssh
+ golang.org/x/oauth2 v0.24.0
golang.org/x/sync v0.10.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
diff --git a/server/internal/file/application/file.go b/server/internal/file/application/file.go
index 25e84f2c..d4845062 100644
--- a/server/internal/file/application/file.go
+++ b/server/internal/file/application/file.go
@@ -61,10 +61,6 @@ type fileAppImpl struct {
base.AppImpl[*entity.File, repository.File]
}
-func (f *fileAppImpl) InjectFileRepo(repo repository.File) {
- f.Repo = repo
-}
-
func (f *fileAppImpl) Upload(ctx context.Context, fileKey string, filename string, r io.Reader) (string, error) {
var err error
fileKey, writer, saveFileFunc, err := f.NewWriter(ctx, fileKey, filename)
diff --git a/server/internal/flow/application/procdef.go b/server/internal/flow/application/procdef.go
index d6f52c95..05fe7165 100644
--- a/server/internal/flow/application/procdef.go
+++ b/server/internal/flow/application/procdef.go
@@ -42,11 +42,6 @@ type procdefAppImpl struct {
var _ (Procdef) = (*procdefAppImpl)(nil)
-// 注入repo
-func (p *procdefAppImpl) InjectProcdefRepo(procdefRepo repository.Procdef) {
- p.Repo = procdefRepo
-}
-
func (p *procdefAppImpl) GetPageList(condition *entity.Procdef, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return p.Repo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
diff --git a/server/internal/flow/application/procinst.go b/server/internal/flow/application/procinst.go
index a521fe65..80d84e4e 100644
--- a/server/internal/flow/application/procinst.go
+++ b/server/internal/flow/application/procinst.go
@@ -51,11 +51,6 @@ type procinstAppImpl struct {
var _ (Procinst) = (*procinstAppImpl)(nil)
-// 注入repo
-func (p *procinstAppImpl) InjectProcinstRepo(procinstRepo repository.Procinst) {
- p.Repo = procinstRepo
-}
-
func (p *procinstAppImpl) GetPageList(condition *entity.ProcinstQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return p.Repo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
diff --git a/server/internal/machine/application/machine.go b/server/internal/machine/application/machine.go
index 9b3fdaa0..32754705 100644
--- a/server/internal/machine/application/machine.go
+++ b/server/internal/machine/application/machine.go
@@ -69,11 +69,6 @@ type machineAppImpl struct {
var _ (Machine) = (*machineAppImpl)(nil)
-// 注入MachineRepo
-func (m *machineAppImpl) InjectMachineRepo(repo repository.Machine) {
- m.Repo = repo
-}
-
// 分页获取机器信息列表
func (m *machineAppImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return m.GetRepo().GetMachineList(condition, pageParam, toEntity, orderBy...)
diff --git a/server/internal/machine/application/machine_cmd_conf.go b/server/internal/machine/application/machine_cmd_conf.go
index 2708323a..cfaed159 100644
--- a/server/internal/machine/application/machine_cmd_conf.go
+++ b/server/internal/machine/application/machine_cmd_conf.go
@@ -36,11 +36,6 @@ type machineCmdConfAppImpl struct {
var _ (MachineCmdConf) = (*machineCmdConfAppImpl)(nil)
-// 注入MachineCmdConfRepo
-func (m *machineCmdConfAppImpl) InjectMachineCmdConfRepo(repo repository.MachineCmdConf) {
- m.Repo = repo
-}
-
func (m *machineCmdConfAppImpl) SaveCmdConf(ctx context.Context, cmdConfParam *dto.SaveMachineCmdConf) error {
cmdConf := cmdConfParam.CmdConf
diff --git a/server/internal/machine/application/machine_cronjob.go b/server/internal/machine/application/machine_cronjob.go
index b2f11b97..239bb256 100644
--- a/server/internal/machine/application/machine_cronjob.go
+++ b/server/internal/machine/application/machine_cronjob.go
@@ -51,11 +51,6 @@ type machineCronJobAppImpl struct {
var _ (MachineCronJob) = (*machineCronJobAppImpl)(nil)
-// 注入MachineCronJobRepo
-func (m *machineCronJobAppImpl) InjectMachineCronJobRepo(repo repository.MachineCronJob) {
- m.Repo = repo
-}
-
// 分页获取机器脚本任务列表
func (m *machineCronJobAppImpl) GetPageList(condition *entity.MachineCronJob, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
diff --git a/server/internal/machine/application/machine_file.go b/server/internal/machine/application/machine_file.go
index 584d1c94..edb4a9f7 100644
--- a/server/internal/machine/application/machine_file.go
+++ b/server/internal/machine/application/machine_file.go
@@ -279,12 +279,15 @@ func (m *machineFileAppImpl) WriteFileContent(ctx context.Context, opParam *dto.
return nil, err
}
- f, err := sftpCli.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE|os.O_RDWR)
+ f, err := sftpCli.OpenFile(path, os.O_RDWR)
if err != nil {
return mi, err
}
+
defer f.Close()
- f.Write(content)
+ if _, err := f.Write(content); err != nil {
+ return mi, err
+ }
return mi, err
}
diff --git a/server/internal/machine/application/machine_script.go b/server/internal/machine/application/machine_script.go
index 716c1b21..1a1d9d97 100644
--- a/server/internal/machine/application/machine_script.go
+++ b/server/internal/machine/application/machine_script.go
@@ -26,11 +26,6 @@ type machineScriptAppImpl struct {
machineApp Machine `inject:"MachineApp"`
}
-// 注入MachineScriptRepo
-func (m *machineScriptAppImpl) InjectMachineScriptRepo(repo repository.MachineScript) {
- m.Repo = repo
-}
-
const Common_Script_Machine_Id = 9999999
// 分页获取机器脚本信息列表
diff --git a/server/internal/machine/application/machine_term_op.go b/server/internal/machine/application/machine_term_op.go
index 98d8bfe9..884e578e 100644
--- a/server/internal/machine/application/machine_term_op.go
+++ b/server/internal/machine/application/machine_term_op.go
@@ -42,11 +42,6 @@ type machineTermOpAppImpl struct {
fileApp fileapp.File `inject:"FileApp"`
}
-// 注入MachineTermOpRepo
-func (m *machineTermOpAppImpl) InjectMachineTermOpRepo(repo repository.MachineTermOp) {
- m.Repo = repo
-}
-
func (m *machineTermOpAppImpl) TermConn(ctx context.Context, cli *mcm.Cli, wsConn *websocket.Conn, rows, cols int) error {
var recorder *mcm.Recorder
var termOpRecord *entity.MachineTermOp
diff --git a/server/internal/mongo/application/mongo.go b/server/internal/mongo/application/mongo.go
index f9468fa9..87a7be64 100644
--- a/server/internal/mongo/application/mongo.go
+++ b/server/internal/mongo/application/mongo.go
@@ -40,11 +40,6 @@ type mongoAppImpl struct {
tagApp tagapp.TagTree `inject:"TagTreeApp"`
}
-// 注入MongoRepo
-func (d *mongoAppImpl) InjectMongoRepo(repo repository.Mongo) {
- d.Repo = repo
-}
-
// 分页获取数据库信息列表
func (d *mongoAppImpl) GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return d.GetRepo().GetList(condition, pageParam, toEntity, orderBy...)
diff --git a/server/internal/redis/application/redis.go b/server/internal/redis/application/redis.go
index 388fc9e7..43e5ea34 100644
--- a/server/internal/redis/application/redis.go
+++ b/server/internal/redis/application/redis.go
@@ -60,11 +60,6 @@ type redisAppImpl struct {
resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"`
}
-// 注入RedisRepo
-func (r *redisAppImpl) InjectRedisRepo(repo repository.Redis) {
- r.Repo = repo
-}
-
// 分页获取redis列表
func (r *redisAppImpl) GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return r.GetRepo().GetRedisList(condition, pageParam, toEntity, orderBy...)
diff --git a/server/internal/sys/application/account.go b/server/internal/sys/application/account.go
index 52a61ad8..68efd495 100644
--- a/server/internal/sys/application/account.go
+++ b/server/internal/sys/application/account.go
@@ -28,11 +28,6 @@ type accountAppImpl struct {
accountRoleRepo repository.AccountRole `inject:"AccountRoleRepo"`
}
-// 注入AccountRepo
-func (a *accountAppImpl) InjectAccountRepo(repo repository.Account) {
- a.Repo = repo
-}
-
func (a *accountAppImpl) GetPageList(condition *entity.AccountQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
}
diff --git a/server/internal/sys/application/config.go b/server/internal/sys/application/config.go
index 4074c715..163dd6ea 100644
--- a/server/internal/sys/application/config.go
+++ b/server/internal/sys/application/config.go
@@ -31,10 +31,6 @@ type configAppImpl struct {
base.AppImpl[*entity.Config, repository.Config]
}
-func (a *configAppImpl) InjectConfigRepo(repo repository.Config) {
- a.Repo = repo
-}
-
func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
}
diff --git a/server/internal/sys/application/resource.go b/server/internal/sys/application/resource.go
index b813998d..919a8d04 100644
--- a/server/internal/sys/application/resource.go
+++ b/server/internal/sys/application/resource.go
@@ -41,11 +41,6 @@ type resourceAppImpl struct {
var _ (Resource) = (*resourceAppImpl)(nil)
-// 注入ResourceRepo
-func (r *resourceAppImpl) InjectResourceRepo(repo repository.Resource) {
- r.Repo = repo
-}
-
func (r *resourceAppImpl) Save(ctx context.Context, resource *entity.Resource) error {
// 更新操作
if resource.Id != 0 {
diff --git a/server/internal/sys/application/role.go b/server/internal/sys/application/role.go
index b95177e2..448a0edf 100644
--- a/server/internal/sys/application/role.go
+++ b/server/internal/sys/application/role.go
@@ -52,10 +52,6 @@ type roleAppImpl struct {
var _ (Role) = (*roleAppImpl)(nil)
-func (r *roleAppImpl) InjectRoleRepo(repo repository.Role) {
- r.Repo = repo
-}
-
func (m *roleAppImpl) GetPageList(condition *entity.RoleQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
}
diff --git a/server/internal/tag/application/resouce_auth_cert.go b/server/internal/tag/application/resouce_auth_cert.go
index bc56845f..896db7a2 100644
--- a/server/internal/tag/application/resouce_auth_cert.go
+++ b/server/internal/tag/application/resouce_auth_cert.go
@@ -54,11 +54,6 @@ type resourceAuthCertAppImpl struct {
tagTreeApp TagTree `inject:"TagTreeApp"`
}
-// 注入Repo
-func (r *resourceAuthCertAppImpl) InjectResourceAuthCertRepo(resourceAuthCertRepo repository.ResourceAuthCert) {
- r.Repo = resourceAuthCertRepo
-}
-
func (r *resourceAuthCertAppImpl) RelateAuthCert(ctx context.Context, params *dto.RelateAuthCert) error {
resourceCode := params.ResourceCode
resourceType := int8(params.ResourceType)
diff --git a/server/internal/tag/application/resource_op_log.go b/server/internal/tag/application/resource_op_log.go
index 4bf25763..8ab4cd3c 100644
--- a/server/internal/tag/application/resource_op_log.go
+++ b/server/internal/tag/application/resource_op_log.go
@@ -26,11 +26,6 @@ type resourceOpLogAppImpl struct {
var _ (ResourceOpLog) = (*resourceOpLogAppImpl)(nil)
-// 注入ResourceOpLogRepo
-func (rol *resourceOpLogAppImpl) InjectResourceOpLogRepo(resourceOpLogRepo repository.ResourceOpLog) {
- rol.Repo = resourceOpLogRepo
-}
-
func (rol *resourceOpLogAppImpl) AddResourceOpLog(ctx context.Context, codePath string) error {
loginAccount := contextx.GetLoginAccount(ctx)
if loginAccount == nil {
diff --git a/server/internal/tag/application/tag_tree.go b/server/internal/tag/application/tag_tree.go
index a6a355bc..6386a99a 100644
--- a/server/internal/tag/application/tag_tree.go
+++ b/server/internal/tag/application/tag_tree.go
@@ -74,11 +74,6 @@ type tagTreeAppImpl struct {
var _ (TagTree) = (*tagTreeAppImpl)(nil)
-// 注入TagTreeRepo
-func (p *tagTreeAppImpl) InjectTagTreeRepo(tagTreeRepo repository.TagTree) {
- p.Repo = tagTreeRepo
-}
-
func (p *tagTreeAppImpl) SaveTag(ctx context.Context, pid uint64, tag *entity.TagTree) error {
accountId := contextx.GetLoginAccount(ctx).Id
// 新建项目树节点信息
diff --git a/server/internal/tag/application/tag_tree_relate.go b/server/internal/tag/application/tag_tree_relate.go
index 5de38588..421f98af 100644
--- a/server/internal/tag/application/tag_tree_relate.go
+++ b/server/internal/tag/application/tag_tree_relate.go
@@ -42,11 +42,6 @@ type tagTreeRelateAppImpl struct {
var _ (TagTreeRelate) = (*tagTreeRelateAppImpl)(nil)
-// 注入TagTreeRelateRepo
-func (p *tagTreeRelateAppImpl) InjectTagTreeRelateRepo(tagTreeRelateRepo repository.TagTreeRelate) {
- p.Repo = tagTreeRelateRepo
-}
-
func (tr *tagTreeRelateAppImpl) RelateTag(ctx context.Context, relateType entity.TagRelateType, relateId uint64, tagCodePaths ...string) error {
if hasConflictPath(tagCodePaths) {
return errorx.NewBizI(ctx, imsg.ErrConflictingCodePath)
diff --git a/server/pkg/base/app.go b/server/pkg/base/app.go
index cde78967..cbcf3bb3 100644
--- a/server/pkg/base/app.go
+++ b/server/pkg/base/app.go
@@ -72,7 +72,7 @@ type App[T model.ModelI] interface {
// 基础application接口实现
type AppImpl[T model.ModelI, R Repo[T]] struct {
- Repo R // repo接口
+ Repo R `inject:"T"` // repo接口, 根据类型进行注入
}
// 获取repo
diff --git a/server/pkg/ioc/component.go b/server/pkg/ioc/component.go
index 772b758f..a1bca302 100644
--- a/server/pkg/ioc/component.go
+++ b/server/pkg/ioc/component.go
@@ -1,5 +1,7 @@
package ioc
+import "reflect"
+
type ComponentOption func(component *Component)
// 组件名
@@ -13,6 +15,8 @@ func WithComponentName(name string) ComponentOption {
type Component struct {
Name string // 组件名
+ Type reflect.Type // 组件类型
+
Value any // 组件实例
}
diff --git a/server/pkg/ioc/ioc.go b/server/pkg/ioc/ioc.go
index c43c1d3a..d455b37f 100644
--- a/server/pkg/ioc/ioc.go
+++ b/server/pkg/ioc/ioc.go
@@ -14,6 +14,11 @@ import (
"golang.org/x/sync/errgroup"
)
+const (
+ InjectTag = "inject"
+ ByTypeComponentName = "T" // 根据类型注入的组件名
+)
+
// 容器
type Container struct {
mu sync.RWMutex
@@ -34,22 +39,25 @@ func (c *Container) Register(bean any, opts ...ComponentOption) {
component := NewComponent(bean, opts...)
componentName := component.Name
- cType := structx.IndirectType(reflect.TypeOf(component.Value))
+ cType := reflect.TypeOf(component.Value)
+ indirectCType := structx.IndirectType(cType)
// 组件名为空,则取组件类型名称作为组件名
if componentName == "" {
- componentName = cType.Name()
+ componentName = indirectCType.Name()
component.Name = componentName
}
+ component.Type = cType
+
if _, ok := c.components[componentName]; ok {
- logx.Warnf("组件名[%s]已经注册至容器, 重复注册...", componentName)
+ logx.Warnf("the component name [%s] has been registered to the container. Repeat the registration...", componentName)
}
- logx.Debugf("ioc register : %s = %s.%s", componentName, cType.PkgPath(), cType.Name())
+ logx.Debugf("ioc register : %s = %s.%s", componentName, indirectCType.PkgPath(), indirectCType.Name())
c.components[componentName] = component
}
-// 注册对象实例的字段含有inject:"xxx"标签或者Setter方法,则注入对应组件实例
+// Inject 注册对象实例的字段含有注入标签或者Setter方法,则注入对应组件实例
func (c *Container) Inject(obj any) error {
objValue := reflect.ValueOf(obj)
if structx.Indirect(objValue).Kind() != reflect.Struct {
@@ -106,49 +114,101 @@ func (c *Container) Get(name string) (any, error) {
return component.Value, nil
}
-// 根据实例字段的inject:"xxx"标签进行依赖注入
+// GetByType 根据组件实例类型获取组件实例
+func (c *Container) GetByType(fieldType reflect.Type) (any, error) {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+
+ for _, component := range c.components {
+ if component.Type.AssignableTo(fieldType) {
+ return component.Value, nil
+ }
+ }
+
+ return nil, errors.New("component type not found: " + fmt.Sprintf("%s.%s", fieldType.PkgPath(), fieldType.Name()))
+}
+
+// injectWithField 根据实例字段的inject:"xxx"或injectByType:""标签进行依赖注入
func (c *Container) injectWithField(objValue reflect.Value) error {
objValue = structx.Indirect(objValue)
objType := objValue.Type()
+ logx.Debugf("start ioc inject with field: %s.%s", objType.PkgPath(), objType.Name())
+
for i := 0; i < objType.NumField(); i++ {
field := objType.Field(i)
+ fieldValue := objValue.Field(i)
- componentName, ok := field.Tag.Lookup("inject")
+ // 检查字段是否是通过组合包含在当前结构体中的,即嵌套结构体
+ if field.Anonymous && structx.IndirectType(field.Type).Kind() == reflect.Struct {
+ c.injectWithField(fieldValue)
+ continue
+ }
+
+ componentName, ok := field.Tag.Lookup(InjectTag)
if !ok {
continue
}
- // inject tag字段名为空则默认为字段名
- if componentName == "" {
- componentName = field.Name
- }
- injectInfo := fmt.Sprintf("ioc field inject [%s -> %s.%s#%s]", componentName, objType.PkgPath(), objType.Name(), field.Name)
- logx.Debugf(injectInfo)
-
- component, err := c.Get(componentName)
- if err != nil {
- return fmt.Errorf("%s error: %s", injectInfo, err.Error())
- }
-
- // 判断字段类型与需要注入的组件类型是否为可赋值关系
- componentType := reflect.TypeOf(component)
- if !componentType.AssignableTo(field.Type) {
- componentType = structx.IndirectType(componentType)
- return fmt.Errorf("%s error: 注入类型不一致(期望类型->%s.%s, 组件类型->%s.%s)", injectInfo, field.Type.PkgPath(), field.Type.Name(), componentType.PkgPath(), componentType.Name())
- }
-
- fieldValue := objValue.Field(i)
- if !fieldValue.IsValid() || !fieldValue.CanSet() {
- // 不可导出变量处理
- fieldPtrValue := reflect.NewAt(fieldValue.Type(), fieldValue.Addr().UnsafePointer())
- fieldValue = fieldPtrValue.Elem()
- if !fieldValue.IsValid() || !fieldValue.CanSet() {
- return fmt.Errorf("%s error: 字段无效或为不可导出类型", injectInfo)
+ // 如果组件名为指定的根据类型注入值,则根据类型注入
+ if componentName == ByTypeComponentName {
+ if err := c.injectByType(objType, field, fieldValue); err != nil {
+ return err
}
+ continue
}
- fieldValue.Set(reflect.ValueOf(component))
+ if err := c.injectByName(objType, field, fieldValue, componentName); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// injectByName 根据实例组件名进行依赖注入
+func (c *Container) injectByName(structType reflect.Type, field reflect.StructField, fieldValue reflect.Value, componentName string) error {
+ // inject tag字段名为空则默认为字段名
+ if componentName == "" {
+ componentName = field.Name
+ }
+
+ injectInfo := fmt.Sprintf("ioc field inject [%s -> %s.%s#%s]", componentName, structType.PkgPath(), structType.Name(), field.Name)
+ logx.Debugf(injectInfo)
+
+ component, err := c.Get(componentName)
+ if err != nil {
+ return fmt.Errorf("%s error: %s", injectInfo, err.Error())
+ }
+
+ // 判断字段类型与需要注入的组件类型是否为可赋值关系
+ componentType := reflect.TypeOf(component)
+ if !componentType.AssignableTo(field.Type) {
+ indirectComponentType := structx.IndirectType(componentType)
+ return fmt.Errorf("%s error: injection types are inconsistent(Expected type -> %s.%s, Component type -> %s.%s)", injectInfo, field.Type.PkgPath(), field.Type.Name(), indirectComponentType.PkgPath(), indirectComponentType.Name())
+ }
+
+ if err := setFieldValue(fieldValue, component); err != nil {
+ return fmt.Errorf("%s error: %s", injectInfo, err.Error())
+ }
+
+ return nil
+}
+
+// injectByType 根据实例类型进行依赖注入
+func (c *Container) injectByType(structType reflect.Type, field reflect.StructField, fieldValue reflect.Value) error {
+ fieldType := field.Type
+
+ injectInfo := fmt.Sprintf("ioc field inject by type [%s.%s -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), structType.PkgPath(), structType.Name(), field.Name)
+ logx.Debugf(injectInfo)
+
+ component, err := c.GetByType(fieldType)
+ if err != nil {
+ return fmt.Errorf("%s error: %s", injectInfo, err.Error())
+ }
+
+ if err := setFieldValue(fieldValue, component); err != nil {
+ return fmt.Errorf("%s error: %s", injectInfo, err.Error())
}
return nil
@@ -174,7 +234,7 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error {
logx.Debugf(injectInfo)
if method.Type.NumIn() != 2 {
- logx.Warnf("%s error: 方法入参不为1个, 无法进行注入", injectInfo)
+ logx.Warnf("%s error: the method cannot be injected if it does not have one parameter", injectInfo)
continue
}
@@ -188,7 +248,7 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error {
expectedComponentType := method.Type.In(1)
if !componentType.AssignableTo(expectedComponentType) {
componentType = structx.IndirectType(componentType)
- return fmt.Errorf("%s error: 注入类型不一致(期望类型->%s.%s, 组件类型->%s.%s)", injectInfo, expectedComponentType.PkgPath(), expectedComponentType.Name(), componentType.PkgPath(), componentType.Name())
+ return fmt.Errorf("%s error: injection types are inconsistent(Expected type -> %s.%s, Component type -> %s.%s)", injectInfo, expectedComponentType.PkgPath(), expectedComponentType.Name(), componentType.PkgPath(), componentType.Name())
}
method.Func.Call([]reflect.Value{objValue, reflect.ValueOf(component)})
@@ -196,3 +256,17 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error {
return nil
}
+
+func setFieldValue(fieldValue reflect.Value, component any) error {
+ if !fieldValue.IsValid() || !fieldValue.CanSet() {
+ // 不可导出变量处理
+ fieldPtrValue := reflect.NewAt(fieldValue.Type(), fieldValue.Addr().UnsafePointer())
+ fieldValue = fieldPtrValue.Elem()
+ if !fieldValue.IsValid() || !fieldValue.CanSet() {
+ return errors.New("the field is invalid or a non-exportable type")
+ }
+ }
+
+ fieldValue.Set(reflect.ValueOf(component))
+ return nil
+}