浅析golang的依赖注入_第1页
浅析golang的依赖注入_第2页
浅析golang的依赖注入_第3页
浅析golang的依赖注入_第4页
浅析golang的依赖注入_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第浅析golang的依赖注入目录前言基于反射的DI基于代码生成的DI

前言

如果是做web开发,对依赖注入肯定不陌生,java程序员早就习惯了spring提供的依赖注入,做业务开发时非常方便,只关注业务逻辑即可,对象之间的依赖关系都交给框架。

golang是强类型语言,编译后是机器码,所以一般使用反射或代码生成解决依赖注入的问题

基于反射的DI

基于反射解决DI问题的框架,使用比较多的是Uber的dig库

官方的例子:

typeConfigstruct{

Prefixstring

//初始化Config函数

funcNewConfig()(*Config,error){

//Inarealprogram,theconfigurationwillprobablybereadfroma

//file.

varcfgConfig

err:=json.Unmarshal([]byte(`{"prefix":"[foo]"}`),cfg)

returncfg,err

//初始化logger函数

funcNewLogger(cfg*Config)*log.Logger{

returnlog.New(os.Stdout,cfg.Prefix,0)

funcHandle()(l*log.Logger){

l.Print("You'vebeeninvoked")

funcmain(){

//初始化dig对象

c:=dig.New()

//Provide方法用来设置依赖的对象

er:=c.Provide(NewConfig)

iferr!=nil{

panic(err)

//设置依赖的对象

err=c.Provide(NewLogger)

iferr!=nil{

panic(err)

//执行Handle()方法

//Handle依赖Config和Logger,使用Invoke执行方法时会自动注入依赖(依赖的对象要传入Provide方法中)

err=c.Invoke(Handle)

iferr!=nil{

panic(err)

//Output:

//[foo]You'vebeeninvoked

}

dig提供了一个容器(container),所有的依赖项通过Provide方法添加,执行某个方法时使用Invoke方法,该方法会自动注入所需要的依赖。

dig使用反射机制解决DI问题,所以代码执行性能上会有损耗

并且因为使用反射所以可能出现编译时没有错误,执行时报空指针

详情使用方法可以参考官方文档,dig可以继承到gin框架中,有兴趣的可以看看资料。

笔者不太喜欢这种使用方式,为了依赖注入破坏了代码原有的调用方式。

基于代码生成的DI

wire库是google出的解决golangDI问题的工具,它可以自动生成依赖注入的代码,节省了手动去处理依赖关系

github地址

wire对原有代码的侵入度很低,开发过程中,在依赖注入代码处调用Build方法(例子中是初始化controller对象)就可以了

//+buildwireinject

packagemain

import(

"encoding/json"

"fmt"

"/google/wire"

"net/http"

typeDataSourcestruct{

Operationstring

funcNewDataSource()DataSource{

returnDataSource{Operation:"operation_name"}

//==================

typeDaostruct{

DataSourceDataSource

funcNewDao(dsDataSource)*Dao{

returnDao{

DataSource:ds,

func(d*Dao)GetItemList()([]string,error){

//TODO拿到DB对象做查询操作

fmt.Printf("dbobject:%s",d.DataSource.Operation)

return[]string{d.DataSource.Operation,"item1","item2"},nil

//====================

typeServicestruct{

Dao*Dao

funcNewService(dao*Dao)*Service{

returnService{Dao:dao}

func(s*Service)GetItemList()([]string,error){

returns.Dao.GetItemList()

//=====================

typeControllerstruct{

Service*Service

funcNewController(service*Service)*Controller{

returnController{Service:service}

func(c*Controller)GetItemList()([]string,error){

returnc.Service.GetItemList()

varMegaSet=wire.NewSet(NewDataSource,NewDao,NewService,NewController)

funcinitializeController()*Controller{

wire.Build(MegaSet)

returnController{}

funcgetItemList(whttp.ResponseWriter,r*http.Request){

controller:=initializeController()

itemList,_:=controller.GetItemList()

output,_:=json.Marshal(itemList)

fmt.Fprintf(w,string(output))

funcmain(){

http.HandleFunc("/items",getItemList)

err:=http.ListenAndServe(":8080",nil)

iferr!=nil{

panic(err)

}

然后再项目根目录执行wire命令,会生成构建好依赖关系的代码(以_gen结尾的文件)

//CodegeneratedbyWire.DONOTEDIT.

//go:generategorun/google/wire/cmd/wire

//+build!wireinject

packagemain

import(

"encoding/json"

"fmt"

"/google/wire"

"net/http"

//Injectorsfrommain.go:

//此处是生成的代码

funcinitializeController()*Controller{

dataSource:=NewDataSource()

dao:=NewDao(dataSource)

service:=NewService(dao)

controller:=NewController(service)

returncontroller

//main.go:

typeDataSourcestruct{

Operationstring

funcNewDataSource()DataSource{

returnDataSource{Operation:"operation_name"}

typeDaostruct{

DataSourceDataSource

funcNewDao(dsDataSource)*Dao{

returnDao{

DataSource:ds,

func(d*Dao)GetItemList()([]string,error){

fmt.Printf("dbobject:%s",d.DataSource.Operation)

return[]string{d.DataSource.Operation,"item1","item2"},nil

typeServicestruct{

Dao*Dao

funcNewService(dao*Dao)*Service{

returnService{Dao:dao}

func(s*Service)GetItemList()([]string,error){

returns.Dao.GetItemList()

typeControllerstruct{

Service*Service

funcNewController(service*Service)*Controller{

returnController{Service:service}

func(c*Controller)GetItemList()([]string,error){

returnc.Service.GetItemList()

varMegaSet=wire.NewSet(NewDataSource,NewDao,NewService,NewController)

funcgetItemList(whttp.ResponseWriter,r*http.Request){

controller:=initializeController()

itemList,_:=controller.GetItemList()

output,_:=json.Marshal(itemList)

fmt.Fprintf(w,string(output))

funcmain(){

http.HandleFunc("/items",getItemList)

err:=http.ListenAndServe(":8080",nil)

iferr!=nil{

panic(err)

}

关键代码:

//执行wire命令前的代码

funcinitializeController()*Controller{

wire.Build(MegaSet)

returnController{}

//执行后生成的代码

//Injectorsfrommain.go:

funcinitializeController()*Controller{

dataSource:=NewDataSource()

dao:=NewDao(da

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论