Gone支持的依赖注入方式

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
云数据库 PolarDB MySQL 版,列存表分析加速 8核16GB
简介: 在Go中,依赖注入通过`gone`标签实现,标记有`gone`的结构体字段在Gone启动时接收依赖。支持值类型、指针类型、接口类型、slice及map类型的注入,但值类型不推荐因拷贝导致独立内存。GonerId用于具名注入,允许可选的GonerId在注册时指定,私有属性也可注入以降低耦合。

为了区分结构体属性是否需要依赖注入,我们引入一个标签——gone,拥有gone标签的属性将在Gone启动过程中被注入需要的依赖。

支持的属性类型

值类型

结构体的属性为某个机构体的值类型,如下面代码中的Boss.Seller

go

复制代码

type Worker struct {
	gone.Flag
	Name      string
}

type Boss struct {
    gone.Flag
    Seller  Worker `gone:"*"`  //值类型
}

::: warning 注意:不推荐使用值类型做注入 “值类型 的赋值和传参都是传递的拷贝”,这意味着我们如果使用 值类型 注入时,实际上产生了一个新的“对象”,新分配了一块内存,并且新旧对象只有在“传递那一刻”是相等,他们在内存中是独立的;这可能导致一些不符合“直觉”的结果,举个例子:

go

复制代码

type BGoner struct {
	gone.Flag

	a1 AGoner  `gone:"A1"` // 值注入
	a2 AGoner  `gone:"A1"` // 值注入
}

func (g *BGoner) AfterRevive() gone.AfterReviveError {
	g.a1.Name = "dapeng"
	g.a2.Name = "wang"

	fmt.Printf("a1 is eq a2: %v", g.a1 == g.a2)

	return nil
}

在上面的代码中,打印的结果会是 false。 :::

指针类型

接收注入的结构体属性是另一个结构体的指针,如下面代码的Boss.Seller的类型为 *Worker:

go

复制代码

type Worker struct {
	gone.Flag
	Name      string
}

type Boss struct {
    gone.Flag
    Seller  *Worker `gone:"*"`  //指针类型
}

接口类型

接收注入的结构体属性是一个接口,如下面代码的Boss.Seller的类型为 Seller,Gone会从注册的Goners中查找实现了Seller接口的Goner赋值给Boss.Seller

go

复制代码

type Seller interface {
    Sell() error
}

type Boss struct {
    gone.Flag
    Seller Seller `gone:"*"`  //接口类型
}

slice 类型

接收注入的结构体属性还可以是 slice 类型,slice 的元素类型允许为 值类型(由于值拷贝,不推荐使用)、指针类型 和 接口类型,如下代码中的Boss.SellersBoss.WorkersBoss.Persons,Gone会尝试间类型兼容的所有goners添加到slice中。

go

复制代码

type Worker struct {
	gone.Flag
	Name      string
}

type Seller interface {
    Sell() error
}

type Boss struct {
    gone.Flag
    Sellers []Seller  `gone:"*"`  //Slice 类型,元素为接口类型
    Workers []*Worker `gone:"*"`   //Slice 类型,元素为指针类型
    Persons []Worker  `gone:"*"`   //Slice 类型,元素为值类型
}

map 类型

接收注入的结构体属性还可以是 map 类型,map 的元素类型允许为 值类型(由于值拷贝,不推荐使用)、指针类型 和 接口类型。map 的 key 只能被定义为string类型,被注入后map key 的值为 GonerId(后面介绍什么是GonerId)。

举个例子

go

复制代码

type Worker struct {
	gone.Flag
	Name      string
}

type Seller interface {
    Sell() error
}

type Boss struct {
    gone.Flag
    Sellers map[string]Seller  `gone:"*"`  //Map 类型,元素为接口类型
    Workers map[string]*Worker `gone:"*"`   //Map 类型,元素为指针类型
    Persons map[string]Worker  `gone:"*"`   //Map 类型,元素为值类型
}

GonerId 和 具名注入

GonerId

Goner注册到Gone框架,支持传递一个可选参数GonerId,如果不传也会随机生成一个,如下:

go

复制代码

type Worker struct {
	gone.Flag
	Name      string
}

type Seller interface {
    Sell() error
}

type Boss struct {
    gone.Flag
    Sellers map[string]Seller  `gone:"*"`  //Map 类型,元素为接口类型
    Workers map[string]*Worker `gone:"*"`   //Map 类型,元素为指针类型
    Persons map[string]Worker  `gone:"*"`   //Map 类型,元素为值类型
}


func Priest(cemetery gone.Cemetery) error {
	cemetery.
		Bury(&Worker{}, gone.GonerId("worker-01")). //注册;使用worker-01做GonerId
		Bury(&Worker{}, gone.GonerId("worker-02")). //注册;使用worker-02做GonerId
		Bury(&Boss{}) //匿名注册,不关心GonerId是什么
	return nil
}

具名注入

前面的例子中,依赖注入标记gone的值都是*,意思让Gone自动寻找或者构建兼容的类型完成注入,我们称之为 匿名注入。另外,Gone支持在gone标签赋予一个值作为GonerId,要求Gone查找特定GonerId的Goner完成依赖注入,也就是 具名注入

如下面代码中,Boss.Manager的注入,Gone会自动寻找GonerId为worker-01的Goner,完成注入。

go

复制代码

type Boss struct {
	gone.Flag
	Manager *Worker `gone:"worker-01"` //具名注入
}

私有属性注入

前面的例子中,所有的属性都是 共有属性 (又称Exported,是大写字母打头的,在包外部可以访问的);Gone实际是支持在私有属性上完成依赖注入的,如下:

go

复制代码

type Boss struct {
	gone.Flag
	manager *Worker `gone:"worker-01"` //manager为私有属性也是可以的
}

我们推荐使用私有属性注入,因为被依赖注入的“对象”一般仅限于内部使用,使用私有属性注入,可以减少代码的耦合度,提高代码的可维护性。


转载来源:https://juejin.cn/post/7382891971858448423

相关文章
|
算法 Unix API
指数退避(Exponential backoff)在网络请求中的应用
## 一、背景 最近做云服务 API 测试项目的过程中,发现某些时候会大批量调用 API,从而导致限流的报错。在遇到这种报错时,传统的重试策略是每隔一段时间重试一次。但由于是固定的时间重试一次,重试时又会有大量的请求在同一时刻涌入,会不断地造成限流。 这让我回想起两年前在查阅[Celery Task 文档](http://docs.celeryproject.org/en/latest
14783 1
|
6月前
|
人工智能 架构师 算法
AI时代,测试工程师的自我重塑
当AI能生成测试用例、预测缺陷,测试工程师的未来何在?答案不是被取代,而是进化。AI将接管重复劳动,释放人力投身复杂逻辑、用户体验与质量体系设计。未来的测试专家需成为AI训练师、质量架构师,深耕机器不擅长的领域。人机协同,方见真章。
|
SQL API 容器
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:后端项目结构说明
GoWind Admin|风行是一款企业级前后端一体中后台框架,后端采用Go语言,基于Protobuf定义API,支持Buf代码生成与Docker部署。项目结构清晰,含API定义、服务实现、数据库ORM、配置管理及自动化脚本,开箱即用,助力高效开发。
567 0
|
消息中间件 运维 监控
小麦助教:通过阿里云原生中间件产品组合,加速微服务架构落地
通过深度的使用阿里云丰富的云原生中间件产品,助力小麦微服务架构的快速落地,借助可观测、消息等产品,极大地提升了开发和运维效率,使小麦在降本增效上有了新的突破,真正做到了只关注业务本身。
5066 98
|
前端开发 小程序 定位技术
Mac上抓包秒通关🐑羊了个羊🐑
前言 看网上大部分是 Windows 微信小游戏的抓包教程通关文章,因为Mac微信不支持小游戏(尴尬了。) 对于真机抓包的话,高版本Android配置CA太麻烦(Root),相信 大部分都是10左右的安卓 手里只有台Mac,那咱就直接用 Mac 配安卓模拟器搞定抓包(Whistle + MuMu) PS:文末有最终演示视频,看效果直接跳文末
|
前端开发 JavaScript Java
基于SSM实现手机销售商城系统
基于SSM实现手机销售商城系统
231 0
|
缓存 负载均衡 Ubuntu
如何在 Ubuntu 20.04 上安装 Nginx
Nginx 发音 “engine x” ,是一个开源软件,高性能 HTTP 和反向代理服务器,用来在互联网上处理一些大型网站。它可以被用作独立网站服务器,负载均衡,内容缓存和针对 HTTP 和非 HTTP 的反向代理服务器。
2054 0
如何在 Ubuntu 20.04 上安装 Nginx
|
2天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
7977 34
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
2天前
|
JavaScript 定位技术 API
CodeGraph 爆火:编程 Agent 需要的不是更多上下文,而是一张提前画好的代码地图
CodeGraph 是一款爆火的本地代码智能工具,通过 tree-sitter 解析 AST 构建结构化知识图谱(存于 SQLite),为编程 Agent 提前生成“代码地图”。它显著降低 Agent 在中大型项目中的探索成本——实测工具调用减少71%、Token 降57%、速度提升46%,支持19+语言及主流框架路由识别,完全离线、无需 API Key。
446 1
CodeGraph 爆火:编程 Agent 需要的不是更多上下文,而是一张提前画好的代码地图