成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么把 Dig 遷移到 Wire

開發 開發工具
dig和wire都是Go依賴注入的工具,那么,本質上功能相似的工具,為什么要從dig切換成 wire?

[[409705]]

本文轉載自微信公眾號「吳親強的深夜食堂」,作者吳親庫里。轉載本文請聯系吳親強的深夜食堂公眾號。

dig和wire都是Go依賴注入的工具,那么,本質上功能相似的工具,為什么要從dig切換成 wire?

場景

我們從場景出發。假設我們的項目分層是:

router->controller->service->dao。

目錄大概就長這樣:

現在我們需要對外暴露一個訂單服務的接口。

首頁看main.go文件。

這里使用了gin啟動項目。

dig

然后我們查看dig.ContainerByDig(),

通過dig.New()創建一個di容器。Provide函數用于添加服務提供者,Provide函數第一個參數本質上是個函數。一個告訴容器 "我能提供什么,為了提供它,我需要什么?" 的函數。

我們看上面的server.NewOrderServer,

這里的NewOrderServer(xxx)在Provide中的語意就是 "我能提供一個OrderServerInterface服務,但是我需要依賴一個dao.OrderDao"。

剛才的代碼中,

因為我們的調用鏈是controller->server->dao,那么本質上他們的依賴是controller<-server<-dao,只是依賴的不是具體的實現,而是抽象的接口。

所以你看到Provide是按照依賴關系順序寫的。

其實完全沒有必要,因為這一步dig只會對這些函數進行分析,提取函數的形參以及返回值。然后根據返回的參數來組織容器結構。并不會在這一步執行傳入的函數,所以在Provide階段前后順序并不重要,只要確保不遺漏依賴項即可。

萬事俱備,我們開始注冊一個能獲取訂單的路由,

此時,調用invoke, 才是真正需要獲取*controller.OrderHandler對象。

調用invoke方法,會對傳入的參數做分析,參數中存在handle *controller.OrderHandler,就會去容器中尋找哪個Provide進來的函數返回類型是handle *controller.OrderHandler,

然后對應找到,

發現這個函數有形參server.OrderServerInterface,那就去找對應返回此類型的函數,

又發現形參(order dao.OrderDao),

最后發現NewOrderDao沒有依賴,不需要再查詢依賴。

開始執行函數的調用NewOrderDao(),把返回的OrderDao

傳入到上層的NewOrderServer(order dao.OrderDao)進行函數調用,

NewOrderServer(order dao.OrderDao)返回的

OrderServerInterface繼續返回到上層

NewOrderHandler(server server.OrderServerInterface)

執行調用,最后再把函數調用返回的*OrderHandler傳遞給

dig.Invoke(func(handle *controller.OrderHandler) {},

整個鏈路就通了。上面看的可能不太舒服,用一個圖來描述這個過程。

dig的整個流程采用的是反射機制,在運行時計算依賴關系,構造依賴對象。

這樣會存在什么問題?

假設我現在注釋掉Provide的一行代碼,比如,

我們在編譯項目的時候并不會報任何錯誤,只會在運行時才發現缺少了依賴項。

wire

還是上面的代碼,我們使用wire作為我們的DI容器。

wire也有兩個核心概念:Provider和Injector。

其中Provider的概念和dig的概念是一樣的:"我能提供什么?我需要什么依賴"。

比如下面wire.go中的代碼,

dao.NewOrderDaoserver.NewOrderServer以及controller.NewOrderHandler就是Provider。

你會發現這里還調用wire.NewSet把他們整合在一起,賦值給了一個變量orderSet。

其實是用到ProviderSet的概念。原理就是把一組相關的Provider進行打包。

這樣的好處是:

  • 結構依賴清晰,便于閱讀。
  • 以組的形式,減少injector里的Build。

至于injector,本質上就是按照依賴關系調用Provider的函數,然后最終生成我們想要的對象(服務)。

比如上面的ContainerByWire()就是一個injector。

那么wire.go文件整體的思路就是:定義好injector,然后實現所需的Provider。

最后在當前wire.go文件夾下執行wire命令后,

此時如果你的依賴項存在問題,那么就會報錯提示。比如我現在隱藏上面的dao.NewOrderDao,那么會出現 ,

如果依賴不存在問題,最終會生成一個wire_gen.go文件。

需要注意上面兩個文件。我們看到wire.go中第一行//+build wireinject,這個build tag確保在常規編譯時忽略wire.go文件。

而與之相對的wire_gen.go中的//+build !wireinject。

兩個對立的build tag是為了確保在任意情況下,兩個文件只有一個文件生效, 避免出現 "ContainerByWire()方法被重新定義" 的編譯錯誤。

現在我們可以真正使用injector了,我們在入口文件中替換成dig。

一切正常。

當然wire有一個點需要注意,在wire.go文件中開頭幾行:

build tag和package他們之間是有空行的,如果沒有空行,build tag識別不了,那么編譯的時候就會報重復聲明的錯誤:

還有很多高級的操作可以自行了解。如果有需要完整代碼請下方留言。

總結

以上大體介紹了 go 中dig和wire兩個DI工具。其中dig是通過運行時反射實現的依賴注入。 而wire是根據自定義的代碼,通過命令,生成相應的依賴注入代碼,在編譯期就完成依賴注入,無需反射機制。 這樣的好處是:

  • 方便排查,如果存在依賴錯誤,編譯時就能發現。而 dig 只能在運行時才能發現依賴錯誤。
  • 避免依賴膨脹,wire生成的代碼只包含被依賴的,而dig可能會存在好多無用依賴。
  • 依賴關系靜態存在源碼,便于工具分析。

Reference

[1]https://github.com/google/wire

[2]https://github.com/uber-go/dig

[3]https://medium.com/@dche423/master-wire-cn-d57de86caa1b

[4]https://www.cnblogs.com/li-peng/p/14708132.html

 

責任編輯:武曉燕 來源: 吳親強的深夜食堂
相關推薦

2021-01-25 07:40:37

Druid數據eBay

2020-04-20 08:08:23

MongoDBElasticsear數據庫

2020-09-09 09:38:47

GoLangNodeJS編程語言

2020-10-13 09:25:27

ESClickHouse搜索引擎

2020-03-12 08:00:34

MySQL遷移TiDB

2020-01-18 09:35:03

微服務團隊架構

2020-09-16 14:56:11

MYSQL知識數據庫

2009-08-06 09:20:30

2022-03-19 16:47:47

WordPress網站遷移服務器

2009-06-16 15:15:18

WebLogic EJ

2017-08-31 17:43:06

云端遷移云計算

2021-04-22 15:55:56

UCaaS統一通信企業通信

2011-04-18 09:36:50

微軟Azure云平臺

2019-06-13 18:18:29

零售商云端遷移

2023-10-19 16:39:38

2018-07-05 14:24:48

ECM云計算SaaS

2021-12-06 13:45:49

云計算云計算環境數據中心

2018-07-04 14:17:10

微服務代碼開發

2023-07-07 08:02:48

TypeScript編譯器文檔

2018-11-15 16:18:14

微服務架構拆分服務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩在线视频精品 | 亚洲国产精品久久 | av在线免费网站 | 少妇黄色 | 一级片视频免费观看 | 天天玩天天干天天操 | 性色av香蕉一区二区 | 午夜激情视频在线 | 成年人网站免费视频 | 国产精品成人品 | 激情a| 91视视频在线观看入口直接观看 | 高清视频一区二区三区 | 亚洲一区在线日韩在线深爱 | 国产欧美二区 | 性色在线| 黄色片免费在线观看 | 国际精品鲁一鲁一区二区小说 | 91国产精品 | 无人区国产成人久久三区 | 成人二区 | 97伦理影院 | 国产精品夜色一区二区三区 | 91精品久久久久久久久99蜜臂 | 国产精品视频网 | 日韩国产精品一区二区三区 | 亚洲美乳中文字幕 | www.干| 中文一区 | 午夜免费视频 | 国产精品色| 中文字幕亚洲国产 | 国产日韩久久 | 亚洲精品视 | 国产电影一区二区在线观看 | 欧美高清视频在线观看 | 欧美一区二区三区久久精品 | 九九九色 | 久久久久久久夜 | 国产欧美一区二区三区国产幕精品 | 欧美日韩在线看 |