github.com/google/wire v0.3.0
然后编写下面的例子
package main
import (
"fmt"
)
type apple struct {
name string
score int
}
func (a *apple) say() string {
return a.name
}
type banana struct {
job string
price int
}
func (b *banana) speak() string {
return b.job
}
type shop struct {
a *apple
b *banana
}
func (s *shop) sail() string {
return s.a.say() + s.b.speak()
}
func Init1() {
a := NewA()
b := NewB()
s := NewS(a, b)
fmt.Println(s.sail())
}
func NewS(a *apple, b *banana) shop {
s := shop{
a: a,
b: b,
}
return s
}
func NewB() *banana {
b := &banana{
job: "/cccc",
price: 0,
}
return b
}
func NewA() *apple {
a := &apple{
name: "asdfasdf",
score: 0,
}
return a
}
func main() {
//Init1()
s := InitializeShop()
sail := s.sail()
fmt.Println(sail)
}
上面的程序正常情况下是不能运行的, 会报错。我们需要在main.go的同级目录下创建一个wire.go文件,其中的内容如下:
// +build wireinject
package main
import "github.com/google/wire"
func InitializeShop() shop {
wire.Build(NewS, NewA, NewB)
return shop{}
}
需要注意,这里的第一行 // +build wireinject十分的重要,不能省略。
下面十分的重要。
在wire.go所在文件夹下执行wire命令(先要使用go mod download 和go mod vendor),这样就会根据规则新建出对象间相互依赖的树。
如下:
// Code generated by Wire. DO NOT EDIT.
//go:generate wire
//+build !wireinject
package main
// Injectors from wire.go:
func InitializeShop() shop {
mainApple := NewA()
mainBanana := NewB()
mainShop := NewS(mainApple, mainBanana)
return mainShop
}
如果其中的类关系或者创建函数有变化,可以直接使用命令 go generate进行重新生成。(当然也可以在ide中直接执行进行刷新)
最终的结构如下图:
最后,需要强调一下。
1、如果在构造函数中有相同的类型,比如,两个struct都有一个构造字段string,那么wire会在进行inject的时候报错,我们需要做的是把其中的一个string重新定义一个类型,比如 type selfstring string,然后让有歧义的string类型变换成selfstring,这样就能够成功注入了。
2、在生成wire_gen.go的时候,如果已经生成了文件,并且本次没有新增函数,Initialize函数,那么可以直接使用wire_gen.go 中的go generate进行重新生成。但是如果新增加了一个类的注入过程,应该使用wire命令重新生成wire_gen.go文件,注意要把
// +build wireinject
注释掉,否则找不到对应的类。
作者:0day__