Go新项目-Gin中wire的依赖注入方式实战(6)

在这里插入图片描述

选型Go项目过程中,针对依赖注入方式的分析和使用

参考资料

  • https://go.dev/blog/wire
  • https://medium.com/@dche423/master-wire-cn-d57de86caa1b
  • https://toutiao.io/posts/et0t2lk/preview
  • https://imlht.com/archives/223/
  • https://lailin.xyz/post/go-training-week4-wire.html
  • https://luenci.me/2022/01/08/%E8%81%8A%E8%81%8AWire%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5/
  • http://c.biancheng.net/view/78.html
  • https://zhuanlan.zhihu.com/p/338926709
  • https://github.com/DuanJiaNing/thewaytowire

wire与其他同类工具的对比

Wire 是一个轻巧的Golang依赖注入工具。它由Go Cloud团队开发,通过自动生成代码的方式在编译期完成依赖注入。

依赖注入是保持软件 “低耦合、易维护” 的重要设计准则之一

同类型哦工具有:来自Uber 的 dig 、来自Facebook 的 inject,下边我们只对比下wire和dig

wire和dig的区别

uber 推出的依赖注入库,采用反射,在运行时计算依赖关系,构造依赖对象。

上面简单介绍了wire 和 dig 两者之间的特点:
1、dig 通过反射识别依赖关系,wire 是编译前计算依赖关系
2、dig 只能在代码运行时,才能知道哪个依赖不对,比如构造函数返回类型的是结构体指针,但是其他依赖的是interface,这样的错误只能在运行时发现,而wire可以在编译的时候就发现。
3、由于采用了依赖注入,所以在代码调试时可以注入一些mock 服务或者函数,wire在mock上支持更友好些,dig的话可以通过build tag 来使用mock。 个人比较推荐使用wire,可以在编译时就发现问题,避免了 多次的build和尝试后才解决编译问题。更多的使用方式和最佳实践,可以参考官方文档。
根据依赖倒置原则(Dependence Inversion Principle),对象应当依赖于接口,而不是直接依赖于具体实现。

使用wire的优势:

  • 方便debug,若有依赖缺失编译时会报错
  • 因为不需要 Service Locators, 所以对命名没有特殊要求
  • 避免依赖膨胀。生成的代码只包含被依赖的代码,而运行时依赖注入则无法作- 到这一点
  • 依赖关系静态存于源码之中, 便于工具分析与可视化

wire 中的两个核心概念: Provider 和 Injector

provider: a function that can produce a value. These functions are ordinary Go code.
injector: a function that calls providers in dependency order. With Wire, you write the injector’s signature, then Wire generates the function’s body.

  • Provider 是一个生成组件的普通函数,这个函数会返回构建依赖关系所需的组件。
  • Injector 是很多个 Provider 组装在一起的时候,可以得到一个管理对象,由wire自动生成的函数。函数内部会按根据依赖顺序调用相关privoder 。

使用wire实战

安装

  • 一、仓库地址:https://github.com/google/wire
  • 二、使用方法:
  • 1、执行 go get github.com/google/wire/cmd/wire 命令
  • 2、执行 go install github.com/google/wire/cmd/wire@latest 命令
  • 3、确认gopath中bin是否存在wire.exe或wire
  • 三、我们的代码目录结构
    route -->> controller–> service -->>Idao -->>dao ->>model

用法效果对比

wire 依赖注入方式想要达到的效果:

我们有一个主函数:

func main() {
message := NewMessage()
greeter := NewGreeter(message)
event := NewEvent(greeter)event.Start()
}

我们改成这样:

func main() {
event := InitializeEvent()
event.Start()
}

代码目录结构

├── routes
│   ├── init_server.go
│   ├── routes.go
│   ├── wire.go
│   └── wire_gen.go

第一步:编写wire.go

//go:build wireinject
// +build wireinjectpackage routesimport (
"gdonline_backend/databases/redis"
"github.com/google/wire"
"github.com/rs/zerolog"
"gorm.io/gorm""gdonline_backend/internal/controller"
"gdonline_backend/internal/dao"
"gdonline_backend/internal/service"
)var chpoPhenotype = wire.NewSet(
dao.NewChpoPhenotypeDao,
wire.Bind(new(dao.IChpoPhenotypesDao), new(*dao.ChpoPhenotypesDao)),
service.NewChpoPhenotypeService,
controller.NewChpoPhenotypesController,
)func InitChpoPhenotypes(db *gorm.DB, log *zerolog.Logger) *controller.ChpoPhenotypesController {
panic(wire.Build(chpoPhenotype))
}

第二步:wire

第三步:生成 wire_gen.go

// Code generated by Wire. DO NOT EDIT.//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinjectpackage routesimport (
"gdonline_backend/databases/redis"
"gdonline_backend/internal/controller"
"gdonline_backend/internal/dao"
"gdonline_backend/internal/service"
"github.com/google/wire"
"github.com/rs/zerolog"
"gorm.io/gorm"
)// Injectors from wire.go:func InitChpoPhenotypes(db *gorm.DB, log *zerolog.Logger) *controller.ChpoPhenotypesController {
chpoPhenotypesDao := dao.NewChpoPhenotypeDao(db, log)
chpoPhenotypesService := service.NewChpoPhenotypeService(chpoPhenotypesDao)
chpoPhenotypesController := controller.NewChpoPhenotypesController(chpoPhenotypesService)
return chpoPhenotypesController
}// wire.go:var chpoPhenotype = wire.NewSet(dao.NewChpoPhenotypeDao, wire.Bind(new(dao.IChpoPhenotypesDao), new(*dao.ChpoPhenotypesDao)), service.NewChpoPhenotypeService, controller.NewChpoPhenotypesController)

第四步:main.go 中调用

# routes>init_server.gofunc InitServer() {
// 初始化数据库连接
db := mysql.DB
redisDB := redis.DB
zeroLog := logging.NewZerolog("business")// 注册服务-wire
cc = InitChpoPhenotypes(db, zeroLog)}# main.go
routes.InitServer()

第五步:实际调用的路由

func Routes(r *gin.Engine) {
// 设置路由组: v1
v1 := r.Group("v1")
chpoPhenotype := v1.Group("chpo_phenotypes")
// 知识库管理
chpoPhenotype.GET("lists", cc.Lists)    // 列表接口
chpoPhenotype.GET("detail", cc.Detail)  // 获取表型详情
chpoPhenotype.POST("add", cc.Add)       // 新增
chpoPhenotype.POST("edit", cc.Edit)     // 编辑
chpoPhenotype.POST("delete", cc.Delete) // 删除
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

即将被AI取代的工作

这个博客 100% 是由人类而不是机器人撰写的。至少在某种程度上,目前仍然需要内容作家。 你的工作怎么样?您是否想过人工智能(AI)是否有可能渗透到您生活的无形本质?您花费数年时间获得的所有知识、技能和经验是否会因…

谈谈前端开发中的防抖和节流

本文作者为 360 奇舞团前端开发工程师 李武阳 概述 防抖和节流是前端开发中常用的函数优化手段,它们可以限制函数的执行频率,提升性能和用户体验。主要用于处理高频触发的事件,例如:用户的滚动、输入、点击和表单的重复提交等。 防…

OceanBase OBCA认证考试预约流程

【OceanBase】OBCA认证考试预约流程 - 课程体系 - 云贝教育https://www.yunbee.net/Home/News/detail/article_id/541.html 一、OBCA账号登录/注册,链接 https://www.oceanbase.com/ob/login/mobile?gotohttps%3A%2F%2Fwww.oceanbase.com%2Ftraining%2Fdetail%3Fle…

Windows Redis图形客户端 Another Redis Desktop Manager的简单使用教程

1、 Redis官方文档 2、 Redis国内中文版文档 3、 Redis客户端 Another Redis Desktop Manager 4、连接redis服务 我直接使用的是公司搭建好的服务。连接服务需要以下几个信息: HostPortPasswordSSL 5、New Key 5.1 如何创建一个Key? 点击New k…

从前端角度浅谈性能 | 京东物流技术团队(转载)

1 前言 自网站诞生以来,页面白屏时间、用户交互的响应速度等一直都是开发者关心的问题,这直接影响了一个网站能否为用户的浏览提供舒适的服务,而这种舒适度,直接关系着对用户的吸引力,毕竟谁都不能忍受一个页面长达10秒…

webassembly003 whisper.cpp的项目结构CMakeLists.txt

注:带星号的为非重要部分 基础配置 cmake_minimum_required (VERSION 3.5)project(whisper.cpp VERSION 1.5.0)# Add path to modules list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") # 在\cmake文件夹下还有BuildTypes.cmake&a…

Uboot-5(U-Boot源码分析1-启动第一阶段)

来源:朱有鹏老师的嵌入式linux核心教程 1、start.S引入 1.1、u-boot.lds中找到start.S入口 (1)、在C语言中整个项目的入口就是main函数(这是C语言规定的),所以譬如说一个有10000个.c文件的项目,第一个要分析的文件就…

Go 中 slice 的 In 功能实现探索

文章目录 遍历二分查找map key性能总结 之前在知乎看到一个问题:为什么 Golang 没有像 Python 中 in 一样的功能?于是,搜了下这个问题,发现还是有不少人有这样的疑问。 补充:本文写于 2019 年。GO 现在已经支持泛型&am…

腾讯云 腾讯云服务器 - 腾讯云 产业智变·云启未来

腾讯云服务器CVM提供安全可靠的弹性计算服务,腾讯云明星级云服务器,弹性计算实时扩展或缩减计算资源,支持包年包月、按量计费和竞价实例计费模式,CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格,提供9个9的数…

【工作记录】基于springboot3+springsecurity6实现多种登录方式(一)

前言 springboot3已经推出有一段时间了,近期公司里面的小项目使用的都是springboot3版本的,安全框架还是以springsecurity为主,毕竟亲生的。 本文针对基于springboot3和springsecurity实现用户登录认证访问以及异常处理做个记录总结&#x…

Linux miniGUI移植分析

框架介绍 常用GUI程序对比 https://www.cnblogs.com/zyly/p/17378659.html MiniGUI分为底层的GAL(图形抽象层)和IAL(输入抽象层),向上为基于标准POSIX接口中pthread库的Mini-Thread架构和基于Server/Client的Mini-L…

JSONObject - 用最通俗的讲解,教你玩转 JSON 数据的解析和修改

目录 一、JSONObject 1.1、为什么要使用他? 1.2、应用 1.2.1、依赖 1.2.2、JSON 数据示例 1.2.3、JSON 数据的构建 1.2.4、JSON 数据的解析 一、JSONObject 1.1、为什么要使用他? 在还没有接触过这个东西的时候,一直是通过 ObjectMap…

Spring 核心之 IOC 容器学习二

基于 Annotation 的 IOC 初始化 Annotation 的前世今生 从 Spring2.0 以后的版本中,Spring 也引入了基于注解(Annotation)方式的配置,注解(Annotation)是 JDK1.5 中引入的一个新特性,用于简化 Bean 的配置,可以取代 XML 配置文件…

深度学习记录--归—化输入特征

归化 归化输入(normalizing inputs),对特征值进行一定的处理,可以加速神经网络训练速度 步骤 零均值化 通过x值更新让均值稳定在零附近,即为零均值化 归化方差 适当减小变量方差 解释 归化可以让原本狭长的数据图像变得规整,梯度下降的…

Electron中苹果支付 Apple Pay inAppPurchase 内购支付

正在开发中,开发好了,写一个完整详细的过程,保证无脑集成即可 一、先创建一个App 一般情况下,在你看这篇文章的时候,说明你已经开发的app差不多了。 但是要上架app到Mac App Store,则要在appstoreconnect…

WPF中Image控件Source的多种指定方式

XAML中 1、直接绝对路径直接给Source 2、将图片放到项目里面,设置图片为资源;Source写法为: (1)Source"pack://application:,,,/label里面的Content;component/folder/test.png" (2&…

HBase学习六:LSM树算法

1、简介 HBase是基于LSM树架构实现的,天生适合写多读少的应用场景。 LSM树本质上和B+树一样,是一种磁盘数据的索引结构。但和B+树不同的是,LSM树的索引对写入请求更友好。因为无论是何种写入请求,LSM树都会将写入操作处理为一次顺序写,而HDFS擅长的正是顺序写(且HDFS不…

鸿蒙应用开发横空出世:是否应该换赛道

鸿蒙应用开发横空出世:互联网寒冬的希望? 大家好,我是demo.最近相信大家最近也收到了这样的消息,网上大肆宣传明年未来的趋势是鸿蒙应用开发,这里呢我也确实被这些信息所覆盖.最近几年确实互联网行业不是很景气,许多公司大量裁员,很多人都因此丢了工作.大龄程序员一直是互联网…

5408. 保险箱

5408. 保险箱 - AcWing题库 #include <iostream> #include <string> #include <algorithm> #include <cstring> using namespace std;const int N 1e5 10; string x, y; int f[N][3], n; int main() {cin >> n >> x >> y;memset(…

Linux第31步_了解STM32MP157的TF-A

了解STM32MP157的TF-A&#xff0c;为后期移植服务。 一、指令集 ARMV8提供了两种指令集:AAarch64和AArch32&#xff0c;根据字面意思就是64位和32位。 ARMV7提供的指令集是AArch32。 二、TF-A 指令集是AArch64的芯片&#xff0c;TF-A有&#xff1a;bl1、bl2、bl31、bl32 和…