GO 依赖注入

2023-11-09

依赖注入是软件工程中经常使用到的一种技术,它提供了一种控制反转的机制,把控制权利交给了调用方。调用方来决定使用哪些参数,哪些对象来进行具体的业务逻辑。

依赖注入的本质其实是为了将组件的创建与其依赖的创建分离

实现原理:

  1. 通过反射读取对象的依赖(golang是通过tag实现)
  2. 在容器中查找有无该对象实例
  3. 如果有该对象实例或者创建对象的工厂方法,则注入对象或使用工厂创建对象并注入
  4. 如果无该对象实例,则报错

好处:
1 它让调用方更灵活。
2 大量减少定义类型的代码量
3 增加代码的可用性,因为调用方只需要关注它需要的参数,不需要顾及它不需要的参数了。

正常我们创建一个对象,首先需要构建对象的构造函数,调用时将入参加入进去,然后其中一旦有一个入参需要更改,所有函数的入参都需要修改:

type Cat struct {
    color String
}

func (cat *Cat) Start() {
    pass
}

func NewCat() *Cat {
    return &Cat{
        color :      "read"
    }
}



type Person struct {
    cat *Cat
}

func (service *Person) Start() []*Person {
    service.cat.Start()
}

func NewPerson(cat *Cat) *Person{
    return &Person{cat: cat}
}

func main() {
    cat := NewCat()
    person := NewPerson(cat)

    person.Satrt()
}

而如果使用以来注入的方式:

type Cat struct {
    color String
}

func (cat *Cat) Start() {
    pass
}

func NewCat() *Cat {
    return &Cat{
        color :      "read"
    }
}



type Person struct {
    cat *Cat
}

func (service *Person) Start() []*Person {
    service.cat.Start()
}

func NewPerson(cat *Cat) *Person{
    return &Person{cat: cat}
}
func BuildContainer() *dig.Container {
    container := dig.New()
    container.Provide(NewCat)
    container.Provide(NewPerson)
    return container
}
func main() {
    container := BuildContainer()

    err := container.Invoke(func(person *Person) {
        person.Start()
    })

    if err != nil {
        panic(err)
    }
}

这个虽然看起来没有简化多少,但是如果依赖的比较多的时候,就需要初始化一堆对象,然后调用对应的函数,而依赖注入:

  • 容器认识到我们要求的是构建 persion
  • 它确定函数 NewPersion提供该类型
  • 接下来它确定 NewPersion函数依赖 Cat
  • 它找到了 Cat 的提供者,也就是 NewCat
  • NewCat 没有任何依赖关系,所以它被调用
  • NewCat 的结果是一个 Cat传递给 NewPersion
  • NewPersion的结果是 *persion 被传递给 Invoke

这个就是依赖注入的本质,

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GO 依赖注入 的相关文章

  • golang中默认的HTTP拨号超时值

    我正在运行 golang http 客户端来对服务器进行压力测试 有时我会收到错误 拨号 tcp 161 170 xx xxx 80 操作超时 错误 我认为这是 HTTP 客户端超时 我正在考虑增加超时值https stackoverflo
  • go build 不断抱怨:go.mod 有 post-v0 模块路径

    Go 1 11 发布后 我一直在尝试将我的存储库移动到 Go 模块 方法是添加go mod文件在其根目录下 我的根库之一my host root其版本为17 0 1 所以我在其中写道go mod file module my host ro
  • 带有导出字段的私有类型

    在 Go 教程的第二天有这样的练习 为什么拥有带有导出字段的私有类型会很有用 例如 package geometry type point struct X Y int name string 请注意point是小写的 因此不会导出 而字段
  • GO中的优先级队列

    谁能向我解释一下 我想在GO中实现一个优先级队列 接口实现来自link https golang org pkg container heap example priorityQueue 但优先级最低 我的代码 pq make Priori
  • Golang 从管道读取读取大量数据

    我正在尝试读取一个正在被焦油化 流式传输到标准输入的存档 但我正在以某种方式读取far管道中的数据多于 tar 发送的数据 我像这样运行我的命令 tar cf somefolder my go binary 源代码是这样的 package
  • 如何获取文件的 ctime、atime、mtime 并更改它们

    如何使用 Go 获取文件的 ctime mtime atime 并更改它们 在 Go 1 1 2 中 os Stat只能获取mtime os Chtimes 可以更改 mtime 和 atime 但不能更改 ctime Linux ctim
  • 如何使用 golang 和 mgo 库在 mongodb 中创建文本索引?

    我正在尝试对集合进行全文搜索 但为了做到这一点 我需要创建一个文本索引 http docs mongodb org manual tutorial create text index on multiple fields http docs
  • 如何自定义解析错误的 HTTP 400 响应?

    我编写了一个 REST API 服务 要求所有响应均为 JSON 但是 当 Go HTTP 请求解析器遇到错误时 它会返回 400 作为纯文本响应 而不会调用我的处理程序 例子 gt curl i H Authorization Basic
  • runtime.LockOSThread 是否允许子 goroutine 在同一个操作系统线程中运行?

    我明白在 Go 中 runtime LockOSThread https golang org pkg runtime LockOSThread将一个 goroutine 绑定到一个操作系统线程 并且不允许其他 goroutine 在该线程
  • 当变量更新时动态刷新模板的一部分golang

    在Golang中 当变量更新时可以刷新模板的一部分吗 例如 我们可以在 Angular js 中找到这一点 基本上在我的代码中 我通过 ajax 中的邮政编码查找地址 它显示我找到的该邮政编码的用户列表 Here is a sample o
  • Golang Appengine 项目无法构建

    我有一个使用 golang 的应用程序引擎项目 我已经大约一年没有碰过了 我现在无法让它在之前构建的机器上构建 我收到以下错误 go app builder 解析输入失败 解析器 src golang org x net internal
  • 使用 crypto/ssh 的 golang scp 文件

    我正在尝试通过 ssh 下载远程文件 以下方法在 shell 上运行良好 ssh hostname tar cz opt local folder gt folder tar gz 然而 golang 上的相同方法在输出工件大小方面存在一些
  • 是否支持动态变量?

    我想知道Go中是否可以动态创建变量 我在下面提供了一个伪代码来说明我的意思 我将新创建的变量存储在切片中 func method slice make type for i 0 i lt 10 i var variable i i slic
  • 投射回更专业的界面

    我正在用 Go 编写一个游戏 在 C 中 我将所有实体类存储在 BaseEntity 类的数组中 如果一个实体需要在世界中移动 那么它将是一个从 BaseEntity 派生的 PhysEntity 但添加了方法 我尝试模仿这是 go pac
  • nsq 无法通过连接到 nsqlookupd 来消费消息

    我尝试使用 docker compose 来运行 nsq docker compose yml如下 version 3 services nsqlookupd image nsqio nsq command nsqlookupd ports
  • 使用 testify 模拟接口方法两次,输入和输出不同

    如何在 golang 测试中模拟接口方法两次 例如 type myCache interface Get key string data interface error type service struct cache myCache f
  • 我可以根据我正在构建的操作系统导入 Golang 包吗?

    假设我有一个基于哪个操作系统的 go 项目 在某些情况下是哪个发行版 我想使用 Systemd 客户端包 Upstart 客户端包 sysv 客户端包 launchd 客户端包 是否可以有选择地导入每个包 以便我只导入我正在构建的每个操作系
  • Go 无法推断赋值中的类型:“non-name on left side of :=”

    该片段按预期工作play golang org p VuCl OKMav http play golang org p VuCl OKMav i 10 next 11 prev i i next 然而这个几乎相同的片段给出了non name
  • 错误“binary.Write:无效类型”是什么意思?

    下面显示的代码 我创建了一个结构类型并希望将其编码为二进制 但它显示binary Write invalid type main Stu错误 我读过一些类似的代码 但我找不到为什么我的代码不起作用 type Stu struct Name
  • 为什么 Go 中只有 int 而没有 float?

    在 Go 中 有这样的类型int这可能相当于int32 or int64取决于系统架构 我可以声明一个整数变量而不用担心它的大小 var x int 为什么没有这个类型float 这相当于float32 or float64取决于我的系统架

随机推荐

  • cv2.threshold() 阈值:使用Python,OpenCV进行简单的图像分割

    图像分割有多种形式 聚类 压缩 边缘检测 区域增长 图分区 分水岭等等 Clustering Compression Edge detection Region growing Graph partitioning Watershed Th
  • table2excel 导出真分页数据如何处理1

    table2excel 导出真分页数据如何处理 首先导入js div class ui edit buttons div
  • python中的一些小trick

    1 set用处 个人之前一直没怎么用过set 直到今天我在写一段代码的时候发现in关键字和set对象简直天生一对 a list if b in a 上面这段代码相信大家都写过 但如果将list对象转换成为set 那么代码速度将大大提升 本质
  • Qt控件----显示窗口部件

    文章目录 显示窗口部件 一 QLabel 1 控件简介 2 用法示例 3 运行效果 二 QCalendarWidget 1 控件简介 2 用法示例 3 运行效果 三 QLCDNumber 1 控件简介 2 用法示例 3 运行效果 四 QPr
  • SQL Part 2 ---常用关键字

    SQL 关键字 常用关键字 Keywords ORDER BY DESC AS Like 星号符 DISTINCT Union INTERSECT EXCEPT 嵌套查询 Nested Query IN NOT IN 在WHERE中使用 I
  • sh ndk-build.cmd command not found

    sh中写ndk build 会报错 ndk build cmd command not found 或者报错 ndk build 未找到命令 解决方法 写ndk build的完整路径 比如 home jason android ndk r1
  • 任务8 使用Word2Vec进行推荐

    任务8 使用Word2Vec进行推荐 1 原理 我们有了用户的embedding很容易就可以利用这些embedding来计算用户的相似度 有了用户的相似度 我们接下来就可以使用前面任务4的一些函数来直接进行推荐 2 代码实现 导入相关的包
  • 关于编程设计模式的简介

    编程设计模式 一 创建模式 Creational Patterns 1 工厂模式 Factory Pattern 2 抽象工厂模式 Abstract Factory Pattern 3 单例模式 Singleton Pattern 4 建造
  • 2020年度总结

    眼看又要年底了 趁着这个双休 给即将过去的 2020 做个简单的总结 今年发生了很多事情 对我的影响很大 年初 2020年1月7日 我入职了上一家公司 在一个 Unity 项目组里做游戏开发 工资虽然不高 但是业务轻车熟路 也在组里涨了不少
  • 使用终端MobaXterm连接Centos

    1 下载MobaXterm 官网 https mobaxterm mobatek net download html 2 MobaXterm连接Linux 1 查看刚才安装的 Linux 的 IP 地址 2 连接 3 Linux自带了JRE
  • 【CUDA编程】线程ID与全局ID的映射关系

    blockDim 方向 指的是该方向上thread的总数 girdDim 方向 指的是该方向上block的总数 1 1D grid 1D block threadId blockIdx x blockDim x threadIdx x 2
  • 阿里巴巴Java开发手册 PDF

    泰山版 更新日期 2020 04 22 链接 https pan baidu com s 1qf252ZN1zMZ16KY ok8uNg 提取码 zxcp 嵩山版 更新日期 2020 08 03 链接 https pan baidu com
  • python与java的一些不同简录

    1 coding UTF 8 2 Python 中单行注释以 开头 多行注释采用三对单引号 或者三对双引号 将注释括起来 3 Python 最具特色的就是使用缩进来表示代码块 缩进的空格数是可变的 但是同一个代码块的语句必须包含相同的缩进空
  • 如何在IEEE的模板中引用Arxiv中的论文

    如何在IEEE的模板中引用Arxiv中的论文 本文章记录如何在IEEE Transactions的模板中 引用Arxiv中的论文 记录具体的论文格式信息 目录 如何在IEEE的模板中引用Arxiv中的论文 1 在IEEE的模板中引用Arxi
  • 匹配算法之 匈牙利算法详解

    参考 算法学习笔记 5 匈牙利算法 漫谈匈牙利算法 匈牙利算法 KM算法 匈牙利算法 二分图 通俗易懂小白入门 二分图最大匹配 匈牙利算法 多目标跟踪之数据关联 匈牙利匹配算法和KM算法 小白学习笔记 一 目标跟踪 匈牙利匹配 一 匈牙利算
  • jQuery Ajax 全解析

    本文地址 jQuery Ajax 全解析 本文作者 QLeelulu 转载请标明出处 jQuery确实是一个挺好的轻量级的JS框架 能帮助我们快速的开发JS应用 并在一定程度上改变了我们写JavaScript代码的习惯 废话少说 直接进入正
  • HBuilderX集成Git教程,需要安装TortoiseGit依赖

    1 HBuilder安装git插件 需要提前安装好git客户端 略过 点击 工具 插件安装 此时还是不能提交代码的 右键选中我们需要的项目 点击 外部命令 Git插件 然后随便选择一个操作 会提示需要安装TortoiseGit 然后跳转到T
  • 归并排序【图解及模板】

    全文目录 归并排序的思想 操作原理 归并排序演示图 代码模板 总结 归并排序的思想 归并排序是建立在归并操作上的一种有效 稳定的排序算法 该算法是采用分治法 Divide and Conquer 的一个非常典型的应用 将已有序的子序列合并
  • keil5改工程名称_Keil5建立stm32工程

    一 准备工作 1 首先在项目名称下建立一个文件夹 作为存放程序的地方 2 在总文件夹下 依次建立User Driver List Output三个文件夹 作为存放main函数 驱动函数 编译和输出文件的子文件夹 二 建立工程 1 打开kei
  • GO 依赖注入

    依赖注入是软件工程中经常使用到的一种技术 它提供了一种控制反转的机制 把控制权利交给了调用方 调用方来决定使用哪些参数 哪些对象来进行具体的业务逻辑 依赖注入的本质其实是为了将组件的创建与其依赖的创建分离 实现原理 通过反射读取对象的依赖