当前位置:首页 > 文章列表 > Golang > Go教程 > go语言依赖注入指的是什么

go语言依赖注入指的是什么

来源:亿速云 2023-03-04 10:42:36 0浏览 收藏

小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《go语言依赖注入指的是什么》,以下内容将会涉及到go语言,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

本篇内容介绍了“go语言依赖注入指的是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

在go语言中,依赖注入(DI)是一种解耦组件之间依赖关系的设计模式;在需要的时候,不同组件之间可以通过一个统一的界面获取其它组件中的对象和状态。依赖注入的好处是解耦;而解耦又能带来更多的好处:代码扩展性增强,代码的可维护性增强,更容易进行单元测试等等。

依赖注入是什么?

第一次听到这个词的时候我是一脸懵逼的,很拗口有没有,可能很多学过spring的同学觉得这是很基础很好理解的知识,但因为我之前没学过Java和spring,所以第一次接触这个词的时候是很懵的。

依赖注入,英文名dependency injection,简称DI。依赖两个字很好理解,在软件设计上,从架构模块到函数方法都存在大大小小的依赖关系。

比如说在new A 之前需要先new B ,A依赖于B,这时候我们就可以说B是A的依赖,A控制B,AB之间存在着耦合的关系,而代码设计思想是最好可以做到松耦合。如果某一天B需要改造那么A也需要跟着改造。这是一个依赖你可以觉得没问题,但如果是A->B->C->D->E->F之间存在一连串的依赖关系,那么改造起来就会十分麻烦。

go语言依赖注入指的是什么

这个时候就需要一种东西来解开他们之间的强耦合,怎么解耦呢,只能借助第三方力量了,我们把A对B的控制权交给第三方,这种思想就称为控制反转(IOC Inversion Of Control),这个第三方称为IOC容器。而IOC容器要做的事情就是new一个B出来,然后把这个B的实例注入到A里面去,然后A就可以正常的使用基于B的方法了,这个过程被称为依赖项注入,而基于IOC的这种方法就叫做依赖注入。

简单来说,依赖注入(DI)是一种解耦组件之间依赖关系的设计模式。在需要的时候,不同组件之间可以通过一个统一的界面获取其它组件中的对象和状态。Go语言的接口设计,避免了很多需要使用第三方依赖注入框架的情况(比如Java,等等)。我们的注入方案只提供非常少的类似Dager或Guice中的注入方案,而专注于尽量避免手动去配置对象和组件之间的依赖关系。

依赖注入的好处

明白了依赖注入的思想,应该也就明白了其带来的最大好处——解耦。

而解耦又能带来更多的好处:代码扩展性增强,代码的可维护性增强,更容易进行单元测试等等。

那么依赖注入如何实现呢?

Java中有以下几种方式:

  • setter方法注入:实现特定属性的public set方法,来让外部容器调用传入所依赖类型的对象。

  • 基于接口的注入:实现特定接口以供外部容器注入所依赖类型的对象。

  • 基于构造函数的注入:实现特定参数的构造函数,在新建对象时传入所依赖类型的对象。

  • 基于注解的注入:在代码里加上特定的关键字实现注入。

注解是最常见的方式,它像注释一样不被当做代码来执行,而是专门供别人阅读。但注释的读者完全是人类,而注解的主要读者除了人类之外还有框架或预编译器。

Go依赖注入-wire

wire就是一种基于注解的依赖注入方式。wire是 Google 开源的一个依赖注入工具,我们只需要在一个特殊的go文件中告诉wire类型之间的依赖关系,它会自动帮我们生成代码,帮助我们创建指定类型的对象,并组装它的依赖。

wire有两个基础概念,Provider(构造器)和Injector(注入器)。

通过提供provider函数,让wire知道如何产生这些依赖对象。wire根据我们定义的injector函数签名,生成完整的injector函数,injector函数是最终我们需要的函数,它将按依赖顺序调用provider

wire的要求很简单,新建一个wire.go文件(文件名可以随意),创建我们的初始化函数。比如,我们要创建并初始化一个Mission对象,我们就可以这样:

//+build wireinject

package main

import "github.com/google/wire"

func InitMission(name string) Mission {
  wire.Build(NewMonster, NewPlayer, NewMission)
  return Mission{}
}

可以看到第一行的注解:+build wireinject,表示这是一个注入器。+build其实是 Go 语言的一个特性。类似 C/C++ 的条件编译,在执行go build时可传入一些选项,根据这个选项决定某些文件是否编译。wire工具只会处理有wireinject的文件,所以我们的wire.go文件要加上这个。

在函数中,我们调用wire.Build()将创建Mission所依赖的类型的构造器传进去。例如,需要调用NewMission()创建Mission类型,NewMission()接受两个参数一个Monster类型,一个Player类型。Monster类型对象需要调用NewMonster()创建,Player类型对象需要调用NewPlayer()创建。所以NewMonster()NewPlayer()我们也需要传给wire

写完wire.go文件之后执行wire命令,就会自动生成一个wire_gen.go文件。

// Code generated by Wire. DO NOT EDIT.

//go:generate wire
//+build !wireinject

package main

// Injectors from wire.go:

func InitMission(name string) Mission {
  player := NewPlayer(name)
  monster := NewMonster()
  mission := NewMission(player, monster)
  return mission
}

可以看到wire自动帮我们生成了InitMission方法,此方法中依次初始化了player,monster和mission。之后在我们的main函数中就只需调用这个InitMission即可。

func main() {
  mission := InitMission("dj")

  mission.Start()
}

而在没用依赖注入之前,我们的代码是这样的:

func main() {
  monster := NewMonster()
  player := NewPlayer("dj")
  mission := NewMission(player, monster)

  mission.Start()
}

是不是简洁了很多。这里只有三个对象的初始化,如果是更多可能才会意识到依赖注入的好处。

比如:

wire.go文件:
// +build wireinject
// The build tag makes sure the stub is not built in the final build.

package di

import (
	"github.com/google/wire"
)

//go:generate kratos t wire
func InitApp() (*App, func(), error) {
	panic(wire.Build(dao.Provider, service.Provider, http.New, grpc.New, NewApp))
}

实现文件:
//dao
var Provider = wire.NewSet(New, NewDB, NewRedis)
//service
var Provider = wire.NewSet(New, wire.Bind(new(pb.Server), new(*Service)))


生成的wire_gen.go 文件:
func InitApp() (*App, func(), error) {
	redis, cleanup, err := dao.NewRedis()
	if err != nil {
		return nil, nil, err
	}
	db, cleanup2, err := dao.NewDB()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	daoDao, cleanup3, err := dao.New(redis, db)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceService, cleanup4, err := service.New(daoDao)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	engine, err := http.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	server, err := grpc.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	app, cleanup5, err := NewApp(serviceService, engine, server)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return app, func() {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

所以,依赖注入到底是什么?

封装解耦罢了。

“go语言依赖注入指的是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注golang学习网,小编将为大家输出更多高质量的实用文章!

到这里,我们也就讲完了《go语言依赖注入指的是什么》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于golang的知识点!

版本声明
本文转载于:亿速云 如有侵犯,请联系study_golang@163.com删除
go语言中反射三定律指的是什么go语言中反射三定律指的是什么
上一篇
go语言中反射三定律指的是什么
go语言有注解吗
下一篇
go语言有注解吗
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • SEO标题魔匠AI:高质量学术写作平台,毕业论文生成与优化专家
    魔匠AI
    SEO摘要魔匠AI专注于高质量AI学术写作,已稳定运行6年。提供无限改稿、选题优化、大纲生成、多语言支持、真实参考文献、数据图表生成、查重降重等全流程服务,确保论文质量与隐私安全。适用于专科、本科、硕士学生及研究者,满足多语言学术需求。
    22次使用
  • PPTFake答辩PPT生成器:一键生成高效专业的答辩PPT
    PPTFake答辩PPT生成器
    PPTFake答辩PPT生成器,专为答辩准备设计,极致高效生成PPT与自述稿。智能解析内容,提供多样模板,数据可视化,贴心配套服务,灵活自主编辑,降低制作门槛,适用于各类答辩场景。
    38次使用
  • SEO标题Lovart AI:全球首个设计领域AI智能体,实现全链路设计自动化
    Lovart
    SEO摘要探索Lovart AI,这款专注于设计领域的AI智能体,通过多模态模型集成和智能任务拆解,实现全链路设计自动化。无论是品牌全案设计、广告与视频制作,还是文创内容创作,Lovart AI都能满足您的需求,提升设计效率,降低成本。
    53次使用
  • 美图AI抠图:行业领先的智能图像处理技术,3秒出图,精准无误
    美图AI抠图
    美图AI抠图,依托CVPR 2024竞赛亚军技术,提供顶尖的图像处理解决方案。适用于证件照、商品、毛发等多场景,支持批量处理,3秒出图,零PS基础也能轻松操作,满足个人与商业需求。
    47次使用
  • SEO标题PetGPT:智能桌面宠物程序,结合AI对话的个性化陪伴工具
    PetGPT
    SEO摘要PetGPT 是一款基于 Python 和 PyQt 开发的智能桌面宠物程序,集成了 OpenAI 的 GPT 模型,提供上下文感知对话和主动聊天功能。用户可高度自定义宠物的外观和行为,支持插件热更新和二次开发。适用于需要陪伴和效率辅助的办公族、学生及 AI 技术爱好者。
    48次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码