【Go】Go wire 依赖注入

news/2025/2/24 13:21:20

1. wire 简介

wire 是一个 Golang 的依赖注入框架(类比 Spring 框架提供的依赖注入功能)

⭐ 官方文档:https://github.com/google/wire

这里关乎到编程世界当中一条好用的设计原则:A用到了B,那么B一定是通过依赖注入的方式提供给A的

举一个例子:现在有一个 CodeService(验证码服务)需要调用到 SmsService(短信服务)来完成发送验证码的功能,此时在 CodeService 内部是不知道也不应该了解如何初始化 SmsService 的,那么就要求由外部传入已经构造好的 SmsService 实例

依赖注入有以下优点:

  • 依赖方与被依赖方耦合度较低
  • 可以复用公共组件(比如 MySQL、Redis 等数据库连接对象)
  • 测试方便
  • 扩展性良好

2. wire 安装与下载

下载 wire 对应源码包:go install github.com/google/wire/cmd/wire@latest

💡 温馨提示:install 命令会自动将 wire 下载到 GOPATH 下的 bin 目录,只有配置该路径环境变量才能使用 wire 命令

3. 项目基本结构

该实例项目参考 DDD 架构规范:

  • repository:领域对象的存储
    • dao:存储到关系型数据库
  • service:领域对象的行为(业务相关)
  • web:与 HTTP 请求交互
  • db.go:初始化数据库连接
  • wire.go:依赖注入代码实现
  • main.go:项目启动入口
  • wire_gen.go:依赖注入生成的文件

repository/dao/user.go

package dao

import "gorm.io/gorm"

type UserDAO struct {
    db *gorm.DB
}

func NewUserDAO(db *gorm.DB) *UserDAO {
    return &UserDAO{
        db: db,
    }
}

repository/user.go

package repository

import "wire_demo/repository/dao"

type UserRepository struct {
	userDAO *dao.UserDAO
}

func NewUserRepository(userDAO *dao.UserDAO) *UserRepository {
	return &UserRepository{
		userDAO: userDAO,
	}
}

service/user.go

package service

import "wire_demo/repository"

type UserService struct {
	repo *repository.UserRepository
}

func NewUserService(repo *repository.UserRepository) *UserService {
	return &UserService{
		repo: repo,
	}
}

web/user.go

package web

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"wire_demo/service"
)

type UserHandler struct {
	userSvc *service.UserService
}

func NewUserHandler(userSvc *service.UserService) *UserHandler {
	return &UserHandler{
		userSvc: userSvc,
	}
}

func (u *UserHandler) SayHello(ctx *gin.Context) {
	ctx.String(http.StatusOK, "Hello,World!")
	return
}

func (u *UserHandler) RegisterRoutes(server *gin.Engine) {
	server.GET("/hello", u.SayHello)
}

db.go

package main

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func InitDB() *gorm.DB {
	db, err := gorm.Open(mysql.Open("root:QWEzxc123456@tcp(localhost:3306)/webook"))
	if err != nil {
		panic(err)
	}
	return db
}

3. wire 快速入门

步骤一:在项目根目录下创建wire.go

//go:build wireinject

package main

import (
    "github.com/google/wire"
    "wire_demo/repository"
    "wire_demo/repository/dao"
    "wire_demo/service"
    "wire_demo/web"
)

func Init() *web.UserHandler {
    wire.Build(
        InitDB,
        dao.NewUserDAO,
        repository.NewUserRepository,
        service.NewUserService,
        web.NewUserHandler,
    )
    return new(web.UserHandler)
}

💡 温馨提示:

  1. 在文件上方使用固定格式 //go:build wireinject 表明这是依赖注入的编译模板文件
  2. 创建一个函数内部使用 wire.Build 方法,传入各种构造方法,wire 会自动分析依赖关系
  3. 返回值无所谓(wire 内部会帮你进行替换)

步骤二:在 wire.go 同级目录下命令行执行wire命令

此时也会发现项目同级目录出现一个wire_gen.go文件,这就是编译生成的文件(内部已经帮你写好了各种构造方法以及依赖之间的传递)

步骤三:在 main.go 文件中正常使用即可!

package main

import "github.com/gin-gonic/gin"

func main() {
	server := gin.Default()
	userHandler := Init()
	userHandler.RegisterRoutes(server)
	server.Run(":8080")
}


http://www.niftyadmin.cn/n/5864379.html

相关文章

【CVPR2024-工业异常检测】PromptAD:与只有正常样本的少样本异常检测的学习提示

代码链接 摘要 摘要写作总结: 1.提出 两个关键点 (视觉语言模型【模型】 少量工业异常检测【方向】) 2.想要解决的问题 3.针对上述问题,本文提出了一种什么【方法】的什么【应用方面】方法【模型名】 4.具体讲方法的步骤 5.实验…

0基础玩转python(打怪升级篇)第一章1.1安装python编辑器

第一章 新手村 1.1合适的武器 (安装python编辑器) 新手村位于代码大陆的东北部,四面环山,高大的城墙外坐落着一条护城河。一位少年缓步走进城内,看到了城内集市热闹非凡。 你叫做“阿印” 是一位勇士 当前等级o Lv 最…

蓝桥杯学习笔记04-滑动窗口不定长(最短/最小)

题目来源 分享丨【题单】滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环) - 力扣(LeetCode) 209. 长度最小的子数组 - 力扣(LeetCode) 题目要求大于等于 class Solution { public:int min…

AWS EC2加速型计算实例全解析:从vt1到p5,如何为AI算力选择最佳引擎?

在人工智能技术高速发展的今天,算力已成为驱动创新的核心动力。AWS EC2加速型计算实例家族凭借其强大的异构计算能力,正在重塑AI开发者的生产力边界。本文将深入解析从vt1.3xlarge到p5.48xlarge的全系列实例,带您找到最适合AI训练与推理的云端…

Python 高级特性-迭代器

目录 迭代器 小结 迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list、tuple、dict、set、str等; 一类是generator,包括生成器和带yield的generator function。 这些可…

在 Mac ARM 架构上使用官方安装包安装 MySQL

在 Mac ARM 架构 (Apple Silicon,例如 M1, M2, M3 芯片) 上使用官方安装包安装 MySQL,步骤与在 Intel Mac 上类似,但需要确保下载的是 ARM 架构兼容的版本。以下是详细的安装步骤: 步骤 1: 下载 MySQL Community Server DMG 安装…

数据结构:基数排序(c++实现)

个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 基数排序的定义和基本原理基本原理具体步骤 基数排序的优缺点:代码实现总结 基数排序的定义和基本原理 基数排序(Radix Sort)是一…

go-zero学习笔记(五)

api自定义中间件 1. 修改.api文件 syntax"v1"type (GetInfoReq {IDs []string json:"IDs"}GetInfoData {ID string json:"ID"Name string json:"Name"MD5 string json:"md5"Size int64 json:"Size"Up…