Skip to content

Commit

Permalink
add: 新增说明
Browse files Browse the repository at this point in the history
  • Loading branch information
cyz-home committed Aug 16, 2024
1 parent 77da225 commit 5f54bf4
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ fmt.Println(user, has, users, count)

## 生成依赖注入_
这里的原始有点像 `wire` 库, 但是不需要额外声明文件和关系, 而是使用通俗约定地生成源码,具体可以查看生成的文件`z_inject_gen.go`

具体使用查看 docs 目录

````go
// Kernel @Bean
type Kernel struct {
Expand Down
28 changes: 26 additions & 2 deletions console/commands/bean.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ func getInitializeNewFunName(k parser.GoTypeAttr, m map[string]string) string {

got := providers + "GetBean(\"" + beanAlias + "\").(" + providers + "Bean)"
if strings.Index(beanValue, "@") != -1 {
// 嵌套时, inject: "@config("app.name")"
// 只支持字符串嵌套注入

startTemp := strings.Index(beanValue, "(")
beanValueNextName := beanValue[1:startTemp]
if beanValue[len(beanValue)-1:] != ")" {
Expand All @@ -252,12 +255,33 @@ func getInitializeNewFunName(k parser.GoTypeAttr, m map[string]string) string {
beanValueNextVal := strings.Trim(beanValue[startTemp+1:], ")")
got = got + ".GetBean(*" + providers + "GetBean(\"" + beanValueNextName + "\").(" + providers + "Bean).GetBean(\"" + beanValueNextVal + "\").(*string))"
} else if tag.Count() <= 2 {
got = got + ".GetBean(\"" + beanValue + "\")"
// 如果没有默认值
if beanValue == "" {
gotType := "*" + alias + name

// 如果`inject:""`检查是否实现Bean接口, 没有实现就不调用
gotFuncStr := `func() {gotType} {
var temp = {providers}GetBean("{beanAlias}")
if bean, ok := temp.({providers}Bean); ok {
return bean.GetBean("").({gotType})
}
return temp.({gotType})
}()`
got = strings.ReplaceAll(gotFuncStr, "{providers}", providers)
got = strings.Replace(got, "{beanAlias}", beanAlias, 1)
got = strings.ReplaceAll(got, "{gotType}", gotType)
return got
} else {
// 必然是实现了Bean接口
got = got + ".GetBean(\"" + beanValue + "\")"
}
} else if tag.Count() == 3 {
// 多个参数||有默认值的注入
beanValue = beanValue + ", " + tag.Get(2)
got = got + ".GetBean(`" + beanValue + "`)"
}

// 如果被注入的是接口时, 这里的*是多余的, 还不支持注入到 type interface 的变量
// 如果有需要, 自行复制z_inject_gen.go内代码, 把开头*和类型*删除,就兼容了
return got + ".(*" + alias + name + ")"
}
}
Expand Down
84 changes: 84 additions & 0 deletions docs/bean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
## Bean 注解
依赖生成工具 [toolset](https://github.com/go-home-admin/toolset); 每个struct如果存在注解 @Bean 那么它就可以被依赖系统管理, 你可以在任意地方编写以下代码,注解依赖工具[`toolset make:bean`](https://github.com/go-home-admin/toolset "`toolset make:bean`"),这个工具可以运行任意项目下,可以不限制本框架。

```go
// @Bean
type Test struct {
TestPort int `inject:"config, app.servers.http.port"`
}
```
上面代码标识,`Test ` 应该有依赖系统管理,属性TestPort 应获得一个`int`类型的配置。配置由`config`服务提供,参数是 `app.servers.http.port``config`服务又是由注解 @Bean("config") 管理,当然它已经在框架引导文件里定义好了,查看 [源码](https://github.com/go-home-admin/home/blob/main/bootstrap/providers/config_provider.go "源码"),你可以参考和定义更强大功能的服务提供者。编写好了,再使用工具生成注释对应的源码。
```shell
make gen
```
执行命令后,工具会在对应目录生成`z_inject_gen.go`,这个文件不应该手动维护;`Test `struct 就可以在其他地方使用了,只是手动`NewTest`, 也可以在别的地方使用`inject`注解注入
```go
func test() {
NewTest()
}
// @Bean
type EchoTest struct {
Test *Test `inject:""`
}
```
## 动态注入
为了更模块化开发,通常一个模块都有一个独立配置文件,以方便扩展功能;例如一个支付模块,需要更改自定义的数据库连接,动态注入指定配置的连接
```go
// @Bean
type Play struct {
DB *gorm.DB `inject:"database, @config(play.connect)"`
}
```

## Bean的生命周期
```go
// @Bean
type DemoBean struct {}

func (receiver DemoBean) Init() {
// 会在第一次NewDemoBean()时候执行
}

func (receiver DemoBean) Boot () {
// 会在框架所有的Init执行后,再统一执行 Boot
}

func (receiver DemoBean) Exit () {
// 应用退出时候统一执行 Exit
}
```

### 接口注入

当前为了快速解析语法树, 没有做挎包读取的功能, 所以需要手动编写代码, 去支持注入

~~~~go
type FromB interface {
B()
}

// 注入 b 实现, 是不能直接支持的
// 这里不要写Bean("a")
type GetB struct {
b FromB `inject:"b"`
}

var _GetBSingle *GetB

// 手动编写代码, 去支持注入
func NewGetB() *GetB {
if _GetBSingle == nil {
_GetBSingle = &GetB{}
_GetBSingle.b = func() FromB {
var temp = providers.GetBean("b")
if bean, ok := temp.(providers.Bean); ok {
return bean.GetBean("").(FromB)
}
return temp.(FromB)
}()
providers.AfterProvider(_GetBSingle, "a")
}
return _GetBSingle
}

~~~~

0 comments on commit 5f54bf4

Please sign in to comment.