当前位置: 首页 > news >正文

快速学Go依赖注入工具wire

Go相对java和C++是较新的语言,但也有诸多优秀特性及生态库。本文介绍大多数软件工程中常用的功能:依赖注入。首先介绍什么是依赖注入,go实现库wire与其他语言的差异。然后通过简单示例实现依赖注入,简化代码、提升可读性。

依赖注入

依赖注入是一种对象接收它所依赖的其他对象(称为依赖项)的技术。通常,接收对象称为客户端,传入(“注入”)对象称为服务。

为了更好理解,下面通过一个简单示例进行说明:

package mainimport ("fmt"
)type Message string
type Greeter struct {Message Message
}
type Event struct {Greeter Greeter
}func GetMessage() Message {return Message("Hello world!")
}func GetGreeter(m Message) Greeter {return Greeter{Message: m}
}func (g Greeter) Greet() Message {return g.Message
}func GetEvent(g Greeter) Event {return Event{Greeter: g}
}func (e Event) Start() {msg := e.Greeter.Greet()fmt.Println(msg)
}func main() {message := GetMessage()greeter := GetGreeter(message)event := GetEvent(greeter)event.Start()
}

上面代码有message, greeter, event;GetMessage函数返回消息,GetGreeter函数接受消息返回greeter,getEvent函数接受返回greeter返回事件。事件还有一个方法start输出消息。

在main函数中,首先创建消息,然后作为依赖传入greeter,最后传给事件。运行程序可以看到输出“Hello world!",这是相对较浅的依赖图,但也能看到其复杂性,这也是依赖注入库wire的价值体现。

Wire简介

Wire是代码依赖工具,它没有采用反射机制或运行时状态,使用Wire可以有效避免手动编写硬代码依赖。Wire在编译时生成源码,官方文档描述: “In Wire, dependencies between components are represented as function parameters, encouraging explicit initialization instead of global variables.” (在Wire中组件之间的依赖关系表示为函数参数,优先采用显式初始化而不是全局变量。)

通过下面命令安装wire:go get github.com/google/wire/cmd/wire;全局安装wire,为后续使用wire命令生成代码:go install github.com/google/wire/cmd/wire

下面我们使用Wire作为依赖注入工具重构上面代码,新增wire.go文件,增加下面代码:

//go:build wireinject
// +build wireinject
package mainimport "github.com/google/wire"func InitializeEvent() Event {wire.Build(GetMessage, GetGreeter, GetEvent)return Event{}
}

首先导入wire,然后创建InitializeEvent函数,该返回在main函数中调用的事件。函数体内调用wire,在构建器方法内传入所有依赖,注意,传入依赖与顺序无关。然后返回空事件,无需担心,所有交给Wire。

注意,文件上面的注释告诉Go在编译时忽略该文件,要确保该注释行后面增加一行空行。

下面是main函数代码:


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

现在成功地把main函数代码降为两行。在wire.go代码目录下,执行wire命令,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 main// Injectors from wire.go:func InitializeEvent() Event {message := GetMessage()greeter := GetGreeter(message)event := GetEvent(greeter)return event
}

同样生成的文件上面注释与wire.go文件相比多了!,表示wire在编译时忽略,go编译时启动。这是运行main函数正确输出结果。

带参数依赖

如果需要动态传入消息作为参数呢?下面我们修改GetMessage函数:

func GetMessage(text string) Message {return Message(text)
}

再次运行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 main// Injectors from wire.go:func InitializeEvent(text string) Event {message := GetMessage(text)greeter := GetGreeter(message)event := GetEvent(greeter)return event
}

现在修改main.go代码:

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

运行结果与期望一致。

如果修改wire.go代码, 模拟缺少部分依赖:

func InitializeEvent(text string) Event {wire.Build(GetMessage, GetEvent)return Event{}
}

执行wire命令,会正确提示少了相应的依赖:

inject InitializeEvent: no provider found for demo01.Greeter needed by demo01.Event in provider "GetEvent" 

总结

本文介绍了基本wire概念,并通过简单示例介绍动态实现依赖注入。但一般wire会在较大项目使用,更多高级功能参考官方文档:https://github.com/google/wire/blob/main/docs/guide.md#advanced-features 。

相关文章:

快速学Go依赖注入工具wire

Go相对java和C是较新的语言,但也有诸多优秀特性及生态库。本文介绍大多数软件工程中常用的功能:依赖注入。首先介绍什么是依赖注入,go实现库wire与其他语言的差异。然后通过简单示例实现依赖注入,简化代码、提升可读性。 依赖注入…...

python入门(4)流程控制语句

1. 条件判断语句 条件控制语句用于根据条件来决定程序的执行路径。在Python中,常见的条件控制语句有以下几种: (1)if语句:用于执行满足条件的代码块。示例代码: age 20 if age > 18:print("成年…...

【进阶】C 语言表驱动法编程原理与实践

数据压倒一切。如果选择了正确的数据结构并把一切组织的井井有条,正确的算法就不言自明。编程的核心是数据结构,而不是算法。——Rob Pike 目录 说明 概念提出 查表方式 直接查找 索引查找 分段查找 实战示例 字符统计 月天校验 名称构造 值名…...

java+springboot留学生新闻资讯网的设计与实现

Spring框架是Java平台的一个开放源代码的Full-stack(全栈)应用程序框架,和控制翻转容器的实现。Spring框架的一些核心功能理论,可以用于所有Java应用,Spring还为Java EE构建的Web应用提供大量的扩展支持。Spring框架没有实现任何的编程模型&a…...

分布式事务与分布式锁区别及概念学习

一、 分布式事务 1.1 背景 传统事务ACID是基于单数据库的本地事务,仅支持单机事务,并不支持跨库事务。但随着微服务架构的普及,业务的分库分表导致一个大型业务系统往往由若干个子系统构成,这些子系统又拥有各自独立的数据库。往往一个业务流程需要由多个子系统共同完成,…...

windows先的conda环境复制到linux环境

如果是迁移的环境一致:同是windows或同是linux直接用这个命令即可: conda create -n new_env_name --clone old_env_path 如果是window的环境迁移到linux这种跨环境就不能用上面的方法,网上这方面的资料也很多,记录一下我的…...

庄懂的TA笔记(十七)<特效:屏幕UV + 屏幕扰动>

庄懂的TA笔记(十七)<特效:屏幕UV 屏幕扰动> 大纲: 目录 庄懂的TA笔记(十七)<特效:屏幕UV 屏幕扰动> 大纲: 正文: 一…...

手写简易RPC框架

目录 简介 服务提供者 服务注册:注册中心 HttpServerHandler处理远程调用请求 consumer服务消费端 简介 RPC(Remote Procedure Call)——远程过程调用,它是一种通过网络从远程计算机程序上请求服务, 而不需要了解…...

基于孪生网络的目标跟踪

一、目标跟踪 目标跟踪是计算机视觉领域研究的一个热点问题,其利用视频或图像序列的上下文信息,对目标的外观和运动信息进行建模,从而对目标运动状态进行预测并标定目标的位置。具体而言,视觉目标(单目标)…...

苏州狮山广场能耗管理系统

摘要:随着社会生活水平的提高,经济的繁荣发展,人们对能源的需求逐渐增长,由此带来的能源危机日益严重。商场如何实时的了解、分析和控制商场的能源消耗已成为需要解决的迫在眉睫的难题。传统的能源消耗智能以月/季度/年为周期进行…...

Jupyter Notebook 10个提升体验的高级技巧

Jupyter 笔记本是数据科学家和分析师用于交互式计算、数据可视化和协作的工具。Jupyter 笔记本的基本功能大家都已经很熟悉了,但还有一些鲜为人知的技巧可以大大提高生产力和效率。在这篇文章中,我将介绍10个可以提升体验的高级技巧。 改变注释的颜色 颜…...

CF 751 --B. Divine Array

Black is gifted with a Divine array a consisting of n (1≤n≤2000) integers. Each position in a has an initial value. After shouting a curse over the array, it becomes angry and starts an unstoppable transformation. The transformation consists of infinite…...

Springcloud1--->Eureka注册中心

目录 Eureka原理Eureka入门案例编写EurekaServer将user-service注册到Eureka消费者从Eureka获取服务 Eureka详解基础架构高可用的Eureka Server失效剔除和自我保护 Eureka原理 Eureka:就是服务注册中心(可以是一个集群),对外暴露自…...

面试阿里、字节全都一面挂,被面试官说我的水平还不如应届生

测试员可以先在大厂镀金,以后去中小厂毫无压力,基本不会被卡,事实果真如此吗?但是在我身上却是给了我很大一巴掌... 所谓大厂镀金只是不卡简历而已,如果面试答得稀烂,人家根本不会要你。况且要不是大厂出来…...

JAVA开发(记一次删除完全相同pgSQL数据库记录只保留一条)

进行数据管理时,无效数据可能会对生产力和决策质量造成严重的影响。如何发现和处理无效数据变得愈发重要。一起来唠唠你会如何处理无效数据吧~ 方向一:介绍无效数据的概念 最近遇到了pg数据库表中的大量数据重复了,需要删除其中的一条。一条…...

音视频八股文(7)-- 音频aac adts三层结构

AAC介绍 AAC(Advanced Audio Coding)是一种现代的音频编码技术,用于数字音频的传输和存储领域。AAC是MPEG-2和MPEG-4标准中的一部分,可提供更高质量的音频数据,并且相比于MP3等旧有音频格式,AAC需要更少的…...

Docker代码环境打包进阶 - DockerHub分享镜像

1. Docker Hub介绍 Docker Hub是一个广泛使用的容器镜像注册中心,为开发人员提供了方便的平台来存储、共享和分发Docker容器镜像。它支持版本控制、访问控制和自动化构建,并提供了丰富的公共镜像库,方便开发人员快速获取和使用各种开源应用和…...

SQL进阶-having子句的力量

SQL进阶-having子句的力量 having子句是理解SQL面向集合这一本质的关键。 在以前的SQL标准里面,having子句必须和group by子句一起使用,但是按照现在的SQL标准,having子句是可以单独使用的 可以与case 表达式或者自连接等结合使用。表不是文件…...

Electron 如何创建模态窗口?

目录 前言一、模态窗口1.Web页面模态框2.Electron中的模态窗口3.区分父子窗口与模态窗口 二、实际案例使用总结 前言 模态框是一种常用的交互元素,无论是在 Web 网站、桌面应用还是移动 APP 中,都有其应用场景。模态框指的是一种弹出窗口,它…...

诺贝尔化学奖:酶分子“定向进化”

2018年,诺贝尔化学奖迎来了历史上第五位女性得主——加州理工学院的Frances H. Arnold教授,以表彰她在“酶的定向进化”这一领域的贡献。 1、“酶的定向进化”到底是什么? 这里有三个点,“酶”、“进化”还有“定向”&#xff1a…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【单片机期末】单片机系统设计

主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

LLM基础1_语言模型如何处理文本

基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求&#xff…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...