go依賴注入管理工具wire的使用方法
wire能做什么?
wire是一個(gè)依賴注入管理的工具。主要包含兩個(gè)角色provider,injector,
- provider: a function that can produce a value.
- injector: a fucntion that calls providers in dependency order.
我們通過簡(jiǎn)單電子商務(wù)網(wǎng)站的例子來看看wire能干什么。假設(shè)有個(gè)購(gòu)物車(ShoppingCart)的對(duì)象,該對(duì)象由多個(gè)產(chǎn)品列表(ProductList)組成,他們的UML關(guān)系如下
具體代碼實(shí)現(xiàn)如下,
type ShoppingCart struct { // 依賴于產(chǎn)品列表 ProductList *ProductList // 其他屬性和方法 } // 產(chǎn)品列表模塊 type ProductList struct { // 一些產(chǎn)品數(shù)據(jù)和方法 } // 創(chuàng)建購(gòu)物車的函數(shù), 這就是依賴注入 // ShoppingCart對(duì)象,需要的部分組件,來自于入?yún)?,而不是函?shù)內(nèi)部構(gòu)建 func NewShoppingCart(pl *ProductList) (*ShoppingCart, error) { return &ShoppingCart{ProductList: pl}, nil } // 創(chuàng)建產(chǎn)品列表的函數(shù) func NewProductList() (*ProductList, error) { return &ProductList{}, nil }
在不使用wire的情況下,如果我們需要使用ShoppingCart
對(duì)象,需要下面這樣一段初始化代碼:
func InitializeShoppingCart() (*ShoppingCart, error) { // 1. 首先構(gòu)建productList productList, err := NewProductList() if err != nil { return nil, err } // 2. 構(gòu)建ShoppingCart shoppingCart, err := NewShoppingCart(productList) if err != nil { return nil, err } return shoppingCart, nil }
這個(gè)例子只涉及到兩個(gè)對(duì)象,所以這段代碼寫起來不費(fèi)力氣。如果這是一個(gè)復(fù)雜的WebServer
對(duì)象呢?我們初始化較多的對(duì)象,比如redisDao,MySQLDao,Kafka,Log,httpServer,grpcServer
等等,這些依賴關(guān)系都需要我們自己處理,那得多麻煩啊。所以,wire就是解決這個(gè)問題的,你可以理解wire幫我們寫了類似于InitializeShoppingCart 這個(gè)函數(shù)。 下面,我們來看看如何使用wire?
wire如何解放雙手?
我們知道wire中有兩個(gè)概念,一個(gè)是provider,一個(gè)是injector,在上面例子中,
- provider:是
NewShoppingCart, NewProductList
這兩個(gè)函數(shù)
他們有一個(gè)共同點(diǎn)是,都創(chuàng)建一個(gè)對(duì)象?,F(xiàn)在我們需要?jiǎng)?chuàng)建一個(gè)指令,告訴wire如何根據(jù)這些provider,寫出InitializaShoppingCart
這個(gè)函數(shù)。我們想想,如果wire是一個(gè)人,你該如何告訴他寫這個(gè)函數(shù)呢?
- 告訴他,這個(gè)函數(shù),最終創(chuàng)建的對(duì)象是什么?也就是
return
是什么?【注,也有一些人這樣寫,傳入的是指針,函數(shù)中所有的操作,就是初始化這個(gè)指針中的內(nèi)容】 - 需要有哪些provider,能夠創(chuàng)建最終的對(duì)象?
明白這兩點(diǎn),我們新建一個(gè)wire.go
的文件,并在開始處寫上+build wireinjector
。接著,寫上這樣一段代碼:
func InitializeShoppingCart() (*ShoppingCart, error) { wire.Build( NewShoppingCart, NewProductList, ) return nil, nil }
然后,在文件所在目錄,執(zhí)行wire
。這個(gè)時(shí)候,會(huì)出現(xiàn)一個(gè)wire_gen.go
的文件。
func InitializeShoppingCart() (*ShoppingCart, error) { productList, err := NewProductList() if err != nil { return nil, err } shoppingCart, err := NewShoppingCart(productList) if err != nil { return nil, err } return shoppingCart, nil }
wire生成的代碼,和我們自己寫的是一樣的。相比于處理復(fù)雜的對(duì)象依賴關(guān)系,寫一個(gè)injector
要簡(jiǎn)單的多。關(guān)于wire的使用,還是有一些坑的,下面我們看看如何避開這些坑。
注意事項(xiàng)
坑一:創(chuàng)建同一個(gè)對(duì)象,只需要一個(gè)provider,不要?jiǎng)?chuàng)建多個(gè)provider。
set has multiple bindings for go-tool/basic/wire1.Fooer
當(dāng)injector中,有多個(gè)provider生成同一個(gè)對(duì)象時(shí),會(huì)報(bào)上述錯(cuò)誤。
坑二:當(dāng)使用接口時(shí),保證上provider生成的是接口,后一個(gè)provider使用的也是接口,同時(shí)保證1對(duì)1關(guān)系;
坑三:如果一個(gè)provider生成的是接口實(shí)現(xiàn)的結(jié)構(gòu)體,另外一個(gè)是provider的入?yún)⑹墙涌?,這個(gè)時(shí)候,需要顯式的使用wire.Bind
函數(shù)告訴接口的具體實(shí)現(xiàn)者。
var set = wire.NewSet(NewFooerImp, NewSecond, wire.Bind(new(Fooer), new(*MyFooer)))
坑四:提供的Provider需要?jiǎng)倓偤茫灰?,也不要少?/p>
- inject InitializeEvent: unused provider "NewEventNumber: 有沒有使用過的provider;
- inject InitializeEvent: no provider found for Greet: 沒有provider;
以上就是go依賴注入管理工具wire的使用方法的詳細(xì)內(nèi)容,更多關(guān)于go wire管理依賴的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang打包成帶圖標(biāo)的exe可執(zhí)行文件
這篇文章主要給大家介紹了關(guān)于golang打包成帶圖標(biāo)的exe可執(zhí)行文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-06-06Golang HTTP 服務(wù)平滑重啟及升級(jí)的思路
Golang HTTP服務(wù)在上線時(shí),需要重新編譯可執(zhí)行文件,關(guān)閉正在運(yùn)行的進(jìn)程,然后再啟動(dòng)新的運(yùn)行進(jìn)程。這篇文章主要介紹了Golang HTTP 服務(wù)平滑重啟及升級(jí),需要的朋友可以參考下2020-04-04關(guān)于golang 字符串 int uint int64 uint64&
這篇文章主要介紹了golang 字符串 int uint int64 uint64 互轉(zhuǎn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01關(guān)于Go語言中特有的設(shè)計(jì)模式與實(shí)現(xiàn)方式講解
雖然Go語言沒有像其他語言那樣明確的設(shè)計(jì)模式,但在實(shí)踐中,開發(fā)者們?nèi)匀话l(fā)現(xiàn)了一些在Go語言中特別適用的設(shè)計(jì)模式和實(shí)現(xiàn)方式,本文就來和大家一一進(jìn)行講解2023-05-05自己動(dòng)手用Golang實(shí)現(xiàn)約瑟夫環(huán)算法的示例
這篇文章主要介紹了自己動(dòng)手用Golang實(shí)現(xiàn)約瑟夫環(huán)算法的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12一文詳解如何在Golang中實(shí)現(xiàn)JWT認(rèn)證與授權(quán)
在現(xiàn)代Web應(yīng)用中,安全性是一個(gè)非常重要的課題,JWT作為一種常用的認(rèn)證與授權(quán)機(jī)制,已被廣泛應(yīng)用于各種系統(tǒng)中,下面我們就來看看如何在Golang中實(shí)現(xiàn)JWT認(rèn)證與授權(quán)吧2025-03-03