go依赖注入wire的使用

转自:https://blog.csdn.net/wild46cat/article/details/103039589

仅作跟人备份,浏览请看原文


 

项目规模小的情况下,是否有依赖注入框架问题不大,但是当项目变大之后,有一个合适的依赖注入框架是十分必要的。通过调研,了解到的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中直接执行进行刷新) 

最终的结构如下图:


项目结构
go依赖注入wire的使用_第1张图片

最后,需要强调一下。

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
注释掉,否则找不到对应的类。

你可能感兴趣的:(go)