google wire是golang的一个依赖注入解决的工具,这个工具可以自动生成类的依赖关系。git
当咱们写代码的时候,都但愿,类都是一个个独立的结构,互不耦合,而类之间的关系,是经过外部传递不一样的依赖组件,来组装出来,生成不一样的实例。github
一个耦合的例子:golang
type BOB struct { db *sql.DB } func NewBOB() *BOB{ return &BOB{ db: new(MysqlDB), } }
在例子中,BOB类会来依赖db类,而db类的生成,是经过new(MysqlDB)生成的,这样就把BOB和db类耦合起来了,若是要改变其余的数据库类,则须要改动BOB的代码了,这样是不合理的,由于BOB依赖的是DB,而不是MysqlDB,最好的方式,MysqlDB类改动了,但BOB代码不用改。sql
下面改一下代码,一个组装依赖的例子:数据库
type BOB struct { db *sql.DB } func NewBOB(db *sql.DB) *BOB{ return &BOB{ db: db, } } func main(){ db := new(MysqlDB) NewBOB(db) }
在上面的例子里,原来的new(MysqlDB),替换为db: db,经过参数的方式来初始化db了,而类的组装是在main函数里面实现,使用这样组装,当MysqlDB改成XXDB的时候,BOB的代码不用变更,代码不用变更,出问题的概率就会少,这样的组装方式,就叫依赖注入了。ide
通常状况下,组装类的依赖关系,均可以手写,但平时写项目的时候,类的数量,很容易会有几十个,这个时候,若是手写的话,会很啰嗦麻烦,并且要理顺好生成的顺序。函数
为了解决依赖组装的问题,golang有uber的dig和Facebook的inject,这两个都是经过运行时注入的,使用运行时注入,会有一些问题,好比很差调试,错误提示不及时等,而wire采用不一样的方式来实现,经过生成依赖注入的代码来解决问题,这样就和手写是同样的,只是减轻手写的麻烦。工具
wire能够经过类组装,结构体组装,还能够参数和异常返回,看看例子:ui
type Foo struct { } func NewFoo() *Foo{ return &Foo{} } type Bar struct { foo *Foo } func NewBar(foo *Foo) *Bar { return &Bar{ foo:foo, } } func (p *Bar) Test(){ fmt.Println("hello") }
wire.go:google
package wire import ( wire "github.com/google/wire" ) type Instance struct { Foo *Foo Bar *Bar } var SuperSet = wire.NewSet(NewFoo, NewBar) func InitializeAllInstance() *Instance { wire.Build(SuperSet, Instance{}) return &Instance{} }
执行wire命令,会读取到wire.NewSet里面的ProviderSet,经过分析各个函数的参数和返回值,来自行解决依赖,能够生成wire_gen.go:
func InitializeAllInstance() *Instance { foo := NewFoo() bar := NewBar(foo) instance := &Instance{ Foo: foo, Bar: bar, } return instance }
经过google wire可以让手写依赖关系变得简单,并且至关直观,值得推荐使用。
[参考资料]