Go依賴注入工具wire的具體使用
Go相對java和C++是較新的語言,但也有諸多優(yōu)秀特性及生態(tài)庫。本文介紹大多數(shù)軟件工程中常用的功能:依賴注入。首先介紹什么是依賴注入,go實現(xiàn)庫wire與其他語言的差異。然后通過簡單示例實現(xiàn)依賴注入,簡化代碼、提升可讀性。
依賴注入
依賴注入是一種對象接收它所依賴的其他對象(稱為依賴項)的技術(shù)。通常,接收對象稱為客戶端,傳入(“注入”)對象稱為服務(wù)。
為了更好理解,下面通過一個簡單示例進行說明:
package main
import (
? ?"fmt"
)
type Message string
type Greeter struct {
? ?Message Message
}
type Event struct {
? ?Greeter Greeter
}
func GetMessage() Message {
? ?return Message("Hello world!")
}
func GetGreeter(m Message) Greeter {
? ?return Greeter{Message: m}
}
func (g Greeter) Greet() Message {
? ?return g.Message
}
func GetEvent(g Greeter) Event {
? ?return Event{Greeter: g}
}
func (e Event) Start() {
? ?msg := e.Greeter.Greet()
? ?fmt.Println(msg)
}
func main() {
? ?message := GetMessage()
? ?greeter := GetGreeter(message)
? ?event := GetEvent(greeter)
? ?event.Start()
}上面代碼有message, greeter, event;GetMessage函數(shù)返回消息,GetGreeter函數(shù)接受消息返回greeter,getEvent函數(shù)接受返回greeter返回事件。事件還有一個方法start輸出消息。
在main函數(shù)中,首先創(chuàng)建消息,然后作為依賴傳入greeter,最后傳給事件。運行程序可以看到輸出“Hello world!",這是相對較淺的依賴圖,但也能看到其復(fù)雜性,這也是依賴注入庫wire的價值體現(xiàn)。
Wire簡介
Wire是代碼依賴工具,它沒有采用反射機制或運行時狀態(tài),使用Wire可以有效避免手動編寫硬代碼依賴。Wire在編譯時生成源碼,官方文檔描述: “In Wire, dependencies between components are represented as function parameters, encouraging explicit initialization instead of global variables.” (在Wire中組件之間的依賴關(guān)系表示為函數(shù)參數(shù),優(yōu)先采用顯式初始化而不是全局變量。)
通過下面命令安裝wire:go get github.com/google/wire/cmd/wire;全局安裝wire,為后續(xù)使用wire命令生成代碼:go install github.com/google/wire/cmd/wire
下面我們使用Wire作為依賴注入工具重構(gòu)上面代碼,新增wire.go文件,增加下面代碼:
//go:build wireinject
// +build wireinject
package main
import "github.com/google/wire"
func InitializeEvent() Event {
? ?wire.Build(GetMessage, GetGreeter, GetEvent)
? ?return Event{}
}首先導(dǎo)入wire,然后創(chuàng)建InitializeEvent函數(shù),該返回在main函數(shù)中調(diào)用的事件。函數(shù)體內(nèi)調(diào)用wire,在構(gòu)建器方法內(nèi)傳入所有依賴,注意,傳入依賴與順序無關(guān)。然后返回空事件,無需擔(dān)心,所有交給Wire。
注意,文件上面的注釋告訴Go在編譯時忽略該文件,要確保該注釋行后面增加一行空行。
下面是main函數(shù)代碼:
func main() {
event := InitializeEvent()
event.Start()
}現(xiàn)在成功地把main函數(shù)代碼降為兩行。在wire.go代碼目錄下,執(zhí)行wire命令,wire會生成wire_gen.go文件:
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func InitializeEvent() Event {
?? ?message := GetMessage()
?? ?greeter := GetGreeter(message)
?? ?event := GetEvent(greeter)
?? ?return event
}同樣生成的文件上面注釋與wire.go文件相比多了!,表示wire在編譯時忽略,go編譯時啟動。這是運行main函數(shù)正確輸出結(jié)果。
帶參數(shù)依賴
如果需要動態(tài)傳入消息作為參數(shù)呢?下面我們修改GetMessage函數(shù):
func GetMessage(text string) Message {
return Message(text)
}再次運行wire命令,可以看到wire_gen.go 代碼也有相應(yīng)修改:
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func InitializeEvent(text string) Event {
?? ?message := GetMessage(text)
?? ?greeter := GetGreeter(message)
?? ?event := GetEvent(greeter)
?? ?return event
}現(xiàn)在修改main.go代碼:
func main() {
event := InitializeEvent("Hello Golang")
event.Start()
}運行結(jié)果與期望一致。
如果修改wire.go代碼, 模擬缺少部分依賴:
func InitializeEvent(text string) Event {
wire.Build(GetMessage, GetEvent)
return Event{}
}執(zhí)行wire命令,會正確提示少了相應(yīng)的依賴:
inject InitializeEvent: no provider found for demo01.Greeter needed by demo01.Event in provider "GetEvent"
總結(jié)
本文介紹了基本wire概念,并通過簡單示例介紹動態(tài)實現(xiàn)依賴注入。但一般wire會在較大項目使用,更多高級功能參考官方文檔:https://github.com/google/wire/blob/main/docs/guide.md#advanced-features 。
到此這篇關(guān)于Go依賴注入工具wire的文章就介紹到這了,更多相關(guān)Go依賴注入工具wire內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析go中的map數(shù)據(jù)結(jié)構(gòu)字典
golang中的map是一種數(shù)據(jù)類型,將鍵與值綁定到一起,底層是用哈希表實現(xiàn)的,可以快速的通過鍵找到對應(yīng)的值。這篇文章主要介紹了go中的數(shù)據(jù)結(jié)構(gòu)字典-map,需要的朋友可以參考下2019-11-11
Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解
這篇文章主要為大家介紹了Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01
golang進行簡單權(quán)限認(rèn)證的實現(xiàn)
本文主要介紹了golang簡單權(quán)限認(rèn)證的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09

