golang依赖注入——wire

Angie ·
更新时间:2024-11-13
· 860 次阅读

最近在做golang的框架,发现golang同样需要类似java中spring一样的ioc依赖注入框架。 如果项目规模小的情况下,是否有依赖注入框架问题不大,但是当项目变大之后,有一个合适的依赖注入框架是十分必要的。 通过调研,了解到的golang中常用的依赖注入框架主要有 inject  dig等等。但是今天要介绍的是wire,一个编译期实现依赖注入的框架。 好,下面上货。 首先添加依赖
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__



wire golang

需要 登录 后方可回复, 如果你还没有账号请 注册新账号