Go工程化 - 依赖注入

我们在微服务框架kratos v2的默认项目模板中kratos-layout使用了google/wire进行依赖注入,也建议开发者在维护项目时使用该工具。

wire 乍看起来比较违反直觉,导致很多同学不理解为什么要用或不清楚如何用(也包括曾经的我),本文来帮助大家理解 wire 的使用。

What

wire是由 google 开源的一个供 Go 语言使用的依赖注入代码生成工具。它能够根据你的代码,生成相应的依赖注入 go 代码。

而与其它依靠反射实现的依赖注入工具不同的是,wire 能在编译期(准确地说是代码生成时)如果依赖注入有问题,在代码生成时即可报出来,不会拖到运行时才报,更便于 debug。

Why

理解依赖注入

什么是依赖注入?为什么要依赖注入?
依赖注入就是 Java 遗毒(不是)

依赖注入 (Dependency Injection,缩写为 DI),可以理解为一种代码的构造模式(就是写法),按照这样的方式来写,能够让你的代码更加容易维护。

对于很多软件设计模式和架构的理念,我们都无法理解他们要绕好大一圈做复杂的体操、用奇怪的方式进行实现的意义。他们通常都只是丢出来一段样例,说这样写就很好很优雅,由于省略掉了这种模式是如何发展出来的推导过程,我们只看到了结果,导致理解起来很困难。那么接下来我们来尝试推导还原一下整个过程,看看代码是如何和为什么演进到依赖注入模式的,以便能够更好理解使用依赖注入的意义。

依赖是什么?

这里的依赖是个名词,不是指软件包的依赖(比如那坨塞在 node_modules 里面的东西),而是指软件中某一个模块(对象/实例)所依赖的其它外部模块(对象/实例)。

注入到哪里?

被依赖的模块,在创建模块时,被注入到(即当作参数传入)模块的里面。

不 DI 是啥样?DI 了又样子?

下面用 go 伪代码来做例子,领会精神即可。

假设个场景,你在打工搞一个 web 应用,它有一个简单接口。最开始的项目代码可能长这个样子:

# 下面为伪代码,忽略了很多与主题无关的细节

type App struct {
   
   
}

# 假设这个方法将会匹配并处理 GET /biu/<id> 这样的请求
func (a *App) GetData(id string) string {
   
   
    # todo: write your data query
    return "some data"
}

func NewApp() *App {
   
   
    return &App{
   
   }
}

app := App()
app.Run()

你要做的是接一个 mysql,从里面把数据按照 id 查出来,返回。
要连 mysql 的话,假设我们已经有了个NewMySQLClient的方法返回 client 给你,初始化时传个地址进去就能拿到数据库连接,并假设它有个Exec的方法给你执行参数。

不用 DI,通过全局变量传递依赖实例

一种写法是,在外面全局初始化好 client,然后 App 直接拿来调用。


var mysqlUrl = "mysql://blabla"
var db = NewMySQLClient(mysqlUrl)


type App struct {
   
   

}

func (a *App) GetData(id string) string {
   
   
    data := db.Exec("select data from biu where id = ? limit 1", id)
    return data
}


func NewApp() *App {
   
   
    return &App{
   
   }
}
func main() {
   
   
    app := App()
    app.Run()
}

这就是没用依赖注入,app 依赖了全局变量 db,这是比较糟糕的一种做法。db 这个对象游离在全局作用域,暴露给包下的其他模块,比较危险。(设想如果这个包里其他代码在运行时悄悄把你的这个 db 变量替换掉会发生啥)

不用 DI,在 App 的初始化方法里创建依赖实例

另一种方式是这样的:

type App struct {
   
   
    db *MySQLClient
}

func (a *App) GetData(id string) string 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值