Go 依赖注入之 wire 库

PS: 若不了解控制反转和依赖注入,可参考博文:控制反转 IoC 与依赖注入 DI

简介

wire 库是管理和解析依赖关系的。

随着项目规模的增长,手动管理依赖关系变得越来越困难,容易导致代码的复杂性和耦合度增加。为了解决这一问题,Google 开发了一个名为 wire 的依赖注入工具,它可以自动生成依赖注入代码,帮助开发者管理依赖关系,提高代码的清晰度和可维护性。

GitHub 地址:https://github.com/google/wire

安装命令

go install github.com/google/wire/cmd/wire@latest

命令使用

在定义的 wire.go 文件所在目录执行 wire 命令即可生成 wire_gen.go 文件

场景示例

以常见的 controller、service、model 模式的依赖注入为例,以下示例为基于 gin 框架的实现:

控制层 userController.go

package controller

// 省略 import

type UserController struct {
	// 注入服务层
	UserService *service.UserService
}

// NewUserController UserController 构造器
// 交给 wire 注入
func NewUserController(userService *service.UserService) *UserController {
	return &UserController{UserService: userService}
}

func (uC *UserController) GetAllUser(c *gin.Context) {
	//
	var body dto.UsersFilterDTO

	if err := c.ShouldBindJSON(&body); err != nil {
		response.Failed(c, response.ParamsError)
		return
	}

	// 调用服务层
	data := uC.UserService.GetAllUser(c, body)

	//
	response.SuccessWithData(c, data)
}

服务层 userService.go

package service

// 省略 import

type UserService struct {
	UserModel *entity.UserModel  // 注入模型类
	// RedisService *RedisService // 注入 Redis 服务
}

// NewUserService UserService 构造器
// 交给 wire 注入
func NewUserService(userModel *entity.UserModel) *UserService {
	return &UserService{UserModel: userModel}
}

func (uS *UserService) GetAllUser(c *gin.Context, body dto.UsersFilterDTO) []vo.UserDetailInfo {
	var users []vo.UserDetailInfo
	if err := db.Model(uS.UserModel).Where(body).Find(&users).Error; err != nil {
		log.Printf("query users err:%v", err)
		panic(err)
	}
	return users
}

wire.go
此文件不会被编译识别,通过在当前文件夹下执行 wire 命令从而生成 wire_gen.go 文件,生成的 InitializeApp 方法被 route.go 中调用

//go:build wireinject
// +build wireinject

package wire

// 省略 import
// 在本文件所在目录下执行 wire 命令

var UserSet = wire.NewSet(
	controller.NewUserController,
	service.NewUserService,
	entity.NewUserModel,
)

var DemoSet = wire.NewSet(
	controller.NewDemoController,
	service.NewDemoService,
	// rabbitMQ.NewRabbitMQService,
)

// AppSet 包含了所有模型的 ProviderSet
var AppSet = wire.NewSet(
	UserSet,
	DemoSet,
	// 可以在这里继续添加其他模块的 ProviderSet
)

type AppControllers struct {
	UserController *controller.UserController
	DemoController *controller.DemoController
}

// InitializeApp 初始化整个应用的控制器, 返回全局应用的 AppControllers
func InitializeApp() (*AppControllers, error) {
	wire.Build(AppSet, wire.Struct(new(AppControllers), "*"))
	return &AppControllers{}, nil
}

route.go
gin 中的路由注册。通过 wire_gen.go 中生成的 InitializeApp 方法获取控制器

appController, _ := wire.InitializeApp()

userGroup := apiGroup.Group("user")
{
	userGroup.POST("info/all", appController.UserController.GetAllUser)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值