go依赖注入管理工具wire的使用方法

 更新时间:2023年09月24日 14:39:30   作者:小范真是一把好手  
本文主要介绍了如何使用go wire管理依赖,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

wire能做什么?

wire是一个依赖注入管理的工具。主要包含两个角色provider,injector,

  • provider: a function that can produce a value.
  • injector: a fucntion that calls providers in dependency order.

我们通过简单电子商务网站的例子来看看wire能干什么。假设有个购物车(ShoppingCart)的对象,该对象由多个产品列表(ProductList)组成,他们的UML关系如下

具体代码实现如下,

type ShoppingCart struct {
    // 依赖于产品列表
    ProductList *ProductList
    // 其他属性和方法
}
// 产品列表模块
type ProductList struct {
    // 一些产品数据和方法
}
// 创建购物车的函数, 这就是依赖注入
// ShoppingCart对象,需要的部分组件,来自于入参,而不是函数内部构建
func NewShoppingCart(pl *ProductList) (*ShoppingCart, error) {
    return &ShoppingCart{ProductList: pl}, nil
}
// 创建产品列表的函数
func NewProductList() (*ProductList, error) {
    return &ProductList{}, nil
}

在不使用wire的情况下,如果我们需要使用ShoppingCart对象,需要下面这样一段初始化代码:

func InitializeShoppingCart() (*ShoppingCart, error) {
	// 1. 首先构建productList
    productList, err := NewProductList()
	if err != nil {
		return nil, err
	}
    // 2. 构建ShoppingCart
	shoppingCart, err := NewShoppingCart(productList)
	if err != nil {
		return nil, err
	}
	return shoppingCart, nil
}

这个例子只涉及到两个对象,所以这段代码写起来不费力气。如果这是一个复杂的WebServer对象呢?我们初始化较多的对象,比如redisDao,MySQLDao,Kafka,Log,httpServer,grpcServer等等,这些依赖关系都需要我们自己处理,那得多麻烦啊。所以,wire就是解决这个问题的,你可以理解wire帮我们写了类似于InitializeShoppingCart 这个函数。 下面,我们来看看如何使用wire?

wire如何解放双手?

我们知道wire中有两个概念,一个是provider,一个是injector,在上面例子中,

  • provider:是NewShoppingCart, NewProductList这两个函数

他们有一个共同点是,都创建一个对象。现在我们需要创建一个指令,告诉wire如何根据这些provider,写出InitializaShoppingCart这个函数。我们想想,如果wire是一个人,你该如何告诉他写这个函数呢?

  • 告诉他,这个函数,最终创建的对象是什么?也就是return是什么?【注,也有一些人这样写,传入的是指针,函数中所有的操作,就是初始化这个指针中的内容】
  • 需要有哪些provider,能够创建最终的对象?

明白这两点,我们新建一个wire.go的文件,并在开始处写上+build wireinjector。接着,写上这样一段代码:

func InitializeShoppingCart() (*ShoppingCart, error) {
	wire.Build(
		NewShoppingCart,
		NewProductList,
	)
	return nil, nil
}

然后,在文件所在目录,执行wire。这个时候,会出现一个wire_gen.go的文件。

func InitializeShoppingCart() (*ShoppingCart, error) {
	productList, err := NewProductList()
	if err != nil {
		return nil, err
	}
	shoppingCart, err := NewShoppingCart(productList)
	if err != nil {
		return nil, err
	}
	return shoppingCart, nil
}

wire生成的代码,和我们自己写的是一样的。相比于处理复杂的对象依赖关系,写一个injector要简单的多。关于wire的使用,还是有一些坑的,下面我们看看如何避开这些坑。

注意事项

坑一:创建同一个对象,只需要一个provider,不要创建多个provider。

set has multiple bindings for go-tool/basic/wire1.Fooer

当injector中,有多个provider生成同一个对象时,会报上述错误。

坑二:当使用接口时,保证上provider生成的是接口,后一个provider使用的也是接口,同时保证1对1关系;

坑三:如果一个provider生成的是接口实现的结构体,另外一个是provider的入参是接口,这个时候,需要显式的使用wire.Bind函数告诉接口的具体实现者。

 var set = wire.NewSet(NewFooerImp, NewSecond, wire.Bind(new(Fooer), new(*MyFooer)))

坑四:提供的Provider需要刚刚好,不要多,也不要少;

  • inject InitializeEvent: unused provider "NewEventNumber: 有没有使用过的provider;
  • inject InitializeEvent: no provider found for Greet: 没有provider;

以上就是go依赖注入管理工具wire的使用方法的详细内容,更多关于go wire管理依赖的资料请关注脚本之家其它相关文章!

相关文章

  • 成功安装vscode中go的相关插件(详细教程)

    成功安装vscode中go的相关插件(详细教程)

    这篇文章主要介绍了成功安装vscode中go的相关插件的详细教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • golang实现协程池的方法示例

    golang实现协程池的方法示例

    本文主要介绍了golang实现协程池的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • Go语言中的匿名结构体用法实例

    Go语言中的匿名结构体用法实例

    这篇文章主要介绍了Go语言中的匿名结构体用法,实例分析了匿名结构体的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go 语言垃圾回收机制从入门到理解

    Go 语言垃圾回收机制从入门到理解

    本文主要介绍了Go 语言垃圾回收机制从入门到理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • 一文详解如何在Golang中实现JWT认证与授权

    一文详解如何在Golang中实现JWT认证与授权

    在现代Web应用中,安全性是一个非常重要的课题,JWT作为一种常用的认证与授权机制,已被广泛应用于各种系统中,下面我们就来看看如何在Golang中实现JWT认证与授权吧
    2025-03-03
  • 深入讲解Go语言中函数new与make的使用和区别

    深入讲解Go语言中函数new与make的使用和区别

    大家都知道Go语言中的函数new与函数make一直是新手比较容易混淆的东西,看着相似,但其实不同,不过解释两者之间的不同也非常容易,下面这篇文章主要给大家介绍了关于Go语言中函数new与make区别的相关资料,需要的朋友可以参考下。
    2017-10-10
  • golang int64转int的方法

    golang int64转int的方法

    这篇文章主要介绍了golang int64转int,本文给大家提供两种方法 ,将 golang int64 转换为golang int,结合实例代码给大家分享转换方法,需要的朋友可以参考下
    2023-01-01
  • Go语言中break label与goto label的区别

    Go语言中break label与goto label的区别

    这篇文章主要介绍了Go语言中break label与goto label的区别,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 深入理解Go语言中defer和panic的执行顺序

    深入理解Go语言中defer和panic的执行顺序

    defer 和 panic 的执行顺序是一个重要的概念,本文主要介绍了Go语言中defer和panic的执行顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-05-05
  • Golang并发控制的三种实现方法

    Golang并发控制的三种实现方法

    在Golang中,有多种方式可以进行并发控制,本文详细的介绍了三种实现方法,Channel优点是实现简单,清晰易懂,WaitGroup优点是子协程个数动态可调整,Context 优点是对子协程派生出来的孙子协程的控制,缺点是相对而言的,要结合实例应用场景进行选择
    2023-08-08

最新评论