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 依赖注入 的相关文章

  • 为什么我不能将左大括号放在下一行?

    当我尝试编译以下代码时遇到奇怪的错误 package main import fmt fmt func main var arr 3 int for i 0 i lt 3 i fmt Printf d arr i 错误如下 unexpect
  • 如何将 int[] 转换为 uint8[]

    所以 我需要你的帮助 我找不到关于该主题的任何内容 Golang 是一门刚刚诞生的语言 所以对于像我这样的新手来说很难快速找到答案 预先声明的 Goint类型大小是特定于实现的 32 位或 64 位 数字类型 http golang org
  • 正确的文件扩展名或缩写是什么。 golang 的文本/模板?

    我正在考虑为其创建语法荧光笔 但我不知道这种特定类型模板的常规缩写 In 例子之一 http golang org pkg text template example Template helpers从文本 模板 godoc 中 它们引用
  • 如何在golang中解析JSON而不需要解组两次

    我有一个 Web 套接字连接 它在 JSON 对象中发送不同类型的消息 并且我想将内容解组到一些已知的结构中 为此 我认为我应该执行以下操作 步骤 1 将 JSON 解组为通用映射 字符串 接口 步骤 2 找到我要找的钥匙 步骤 3 尝试将
  • “go.tools”的权限被拒绝错误

    当我尝试安装 go 工具时 我的权限被拒绝 usr local go pkg tool linux amd64 cover 我可以接受 因为它是 usr local 目录及需求root使用权 但我的第一个疑问是为什么当我设置时它试图安装在这
  • 如何仅在测试时允许一个包访问另一个包的未导出数据?

    In Go 编程语言 第 11 2 4 节 有一个外部测试访问的示例fmt isSpace 通过声明IsSpace in fmt s export test go文件 这似乎是完美的解决方案 所以这就是我所做的 a a go package
  • 如何关闭 gorm 1.20.0 中的数据库实例

    由于我没有在 Close 函数中找到 gorm 实例 任何帮助将不胜感激 dbURI fmt Sprintf user s password s dbname s port s sslmode s TimeZone s username p
  • 如何确定 go 中当前运行的可执行文件的完整路径?

    我一直在 osx 上使用这个函数 Shortcut to get the path to the current executable func ExecPath string var here os Args 0 if strings H
  • 为什么 gmail API 以纯文本形式发送 html 电子邮件?

    我正在尝试使用 gmail API 发送 html 电子邮件 但由于某些原因 它会随机以纯文本 文本形式发送电子邮件 谷歌似乎改变了我设置的内容类型标头 这有什么理由吗 电子邮件内容始终完全相同 正如我测试的那样 API 仍处于实验阶段吗
  • 在 Go to 函数中通过引用和值传递

    我对 Go 中通过引用和值传递有点困惑 我已经看到过对类型前面的 的解释 在类型名称前面 表示声明的变量将存储该类型的另一个变量的地址 而不是该类型的值 类型 这对我来说毫无意义 在Java中 如果我将数据库实例传递给函数 我会这样做 da
  • 错误:标准包中非标准导入“gopkg.in/yaml.v2”

    我正在尝试从以下位置导入 go yamlhttps github com go yaml yaml https github com go yaml yaml 并且我发现了一个 Google 没有提供帮助的错误 I ran go get g
  • golang.org 包和标准库之间的区别

    我使用 go 已经有一段时间了 我注意到 Go 标准库 和 golang org x 之间存在重复的包 我的问题是 为什么它们被释放两次 在这两者中 我应该使用哪一个 更新的 规范的等 到目前为止我注意到的一些示例包已发布两次 golang
  • 将产生 goroutine 的 golang 方法

    据我所知 如果 goroutine 太忙 它们会阻止其他 goroutine 运行 对我来说 这意味着我的应用程序的性能和响应能力可能取决于我知道哪些库方法将控制其他 goroutine 例如通常是 Read 和 Write 有什么方法可以
  • 有没有办法间歇性地执行重复性任务?

    有没有办法在 Go 中执行重复的后台任务 我在想类似的事情Timer schedule task delay period 在爪哇 我知道我可以用 goroutine 来做到这一点Time sleep 但我想要一些容易停止的东西 这是我得到
  • 我们如何在 Go 中使用通道来代替互斥锁?

    通道将通信 值的交换 与同步相结合 保证两个计算 goroutine 处于已知状态 如何使用 Google Go 中的通道来执行互斥量的功能 package main import sync var global int 0 var m s
  • pprof 和 ps 之间的内存使用差异

    我一直在尝试分析用 cobra 构建的 cli 工具的堆使用情况 这pprof工具显示如下 Flat Flat Sum Cum Cum Name Inlined 1 58GB 49 98 49 98 1 58GB 49 98 os Read
  • 测试 gRPC 服务

    我想测试用 Go 编写的 gRPC 服务 我使用的示例是 Hello World 服务器示例grpc go 仓库 https github com grpc grpc go blob master examples helloworld g
  • json.Unmarshal json字符串到对象是空结果[重复]

    这个问题在这里已经有答案了 我有一个非常简单的程序 如下所示 package main import encoding json fmt type RunCommand struct level string json level call
  • 如何使用 go1.6.2 构建 linux 32 位

    有没有任何组合GOARCH and GOOS我可以设置哪些值来构建 ELF 32 位二进制文 件 GOOS linux and GOARCH 386 更多示例 架构 32 bit gt GOARCH 386 64 bit gt GOARCH
  • 如何通过在切片上查找来从切片复制到数组

    我正在编写一个库来处理二进制格式 我有一个带有数组变量的结构 我想保留它以用于文档目的 我还需要从输入字节片中查找和判断 一些伪代码 type foo struct boo 5 byte coo 3 byte func main input

随机推荐

  • 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 依赖注入

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