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秒…

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…

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

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

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

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

HBase学习六:LSM树算法

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

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

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

再见了RDM,Redis官方GUI才是最好的!

1 简介 直观高效的 Redis GUI 管理工具,它可以对 Redis 的内存、连接数、命中率以及正常运行时间进行监控,并且可以在界面上使用 CLI 和连接的 Redis 进行交互(RedisInsight 内置对 Redis 模块支持),官方下载地址。 使…

Power Designer 连接 PostgreSQL 逆向工程生成pd表结构操作步骤以及过程中出现的问题解决

一、使用PowerDesigner16.5 链接pg数据库 1.1、启动PD.选择Create Model…。 1.2、选择Model types / Physical Data Model Physical Diagram:选择pgsql直接【ok】 1.3、选择connect 在工具栏选择Database-Connect… 快捷键:ctrlshiftN.如下图&#xff…

查询数据库表字段具有某些特征的表

目录 引言举例总结 引言 当我们把一个项目做完以后,客户要求我们把系统中所有的电话,证件号等进行加密处理时,我们难道要一个表一表去查看那些字段是电话和证件号码吗? 这种办法有点费劲,下面我们来探索如何找到想要的…

CVE-2024-0195-SpiderFlow爬虫平台远程命令执行漏洞分析

项目下载地址 spider-flow: 新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。https://gitee.com/ssssssss-team/spider-flow 在平台spiderflow的页面中有一个自定义函数,看到函数应是非常的敏感了。 可以做一些猜想与尝试&…

「优选算法刷题」:盛最多水的容器

一、题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器…

RT Thread Stdio生成STM32L431RCT6无法启动问题

一、问题现象 使用RT thread Stdio生成STM32L431RCT6工程后,编译下载完成后系统无法启动,无法仿真debug; 二、问题原因 如果当前使用的芯片支持包版本为0.2.3,可能是这个版本问题,目前测试0.2.3存在问题&#xff0c…