wire 庫是gogole開發(fā)的go依賴注入庫。了解更多,請點擊一文讀懂wire
我們建議使用wire的時候遵循以下建議
區(qū)分類型
如果需要注入常見類型(字符串,整型等),請創(chuàng)建一個新類型,以避免與其他提供程序發(fā)生沖突。例如:
type MySQLConnectionString string
Options Structs
包含許多參數(shù)的provider函數(shù), 考慮把參數(shù)打包成一個結(jié)構(gòu)體
type Options struct {
// Messages is the set of recommended greetings.
Messages []Message
// Writer is the location to send greetings. nil goes to stdout.
Writer io.Writer
}
func NewGreeter(ctx context.Context, opts Options) (Greeter, error) {
// ...
}
var GreeterSet = wire.NewSet(wire.Struct(new(Options), "*"), NewGreeter)
功能包中的 Provider Sets
按go包中創(chuàng)建的 provider sets中,要保持兼容性,僅可以做如下修改:
刪除provider 函數(shù)的參數(shù),但是不能給函數(shù)添加新的參數(shù),不能改變函數(shù)的返回值。
provider 函數(shù)添加一個全新類型的返回值,注意:必須是全新類型,如果類型不是新添加的,可能會和某個包含此類型的injector產(chǎn)生沖突。
如下圖,T2 必須是全新的類型,否則很可能會產(chǎn)生沖突
除此以外的所有修改都是不安全的,包括:
在此provido 函數(shù)中添加新的參數(shù)
從 providor 函數(shù)刪除一個返回值
添加一個已存在的輸出到providor set中
??:與其進行這些重大更改,不如考慮添加一個新的providor set。
例如,如果您有這樣的提供程序集:
var GreeterSet = wire.NewSet(NewStdoutGreeter)
func DefaultGreeter(ctx context.Context) *Greeter {
// ...
}
func NewStdoutGreeter(ctx context.Context, msgs []Message) *Greeter {
// ...
}
func NewGreeter(ctx context.Context, w io.Writer, msgs []Message) (*Greeter, error) {
// ...
}
你可以:
在 Greeter 中,使用 DefaultGreeter 替代 NewStdoutGreeter
創(chuàng)建一個新類型 T, 添加 T 的 providor 到 GreeterSet 中,只要 T 是和 provider 一同新加的。
但你不能做如下操作:
在 GreeterSet 中 使用 NewGreeter 替換 NewStdoutGreeter。這添加了新參數(shù)(io.Writer), 并添加了一個新的error 返回
從 Geeter 中移除 NewStdoutGreeter, 依賴 Greeter 的注入器可能被破壞
添加一個 io.Writer provider 到 GeeeterSet。 注入器可能在其他地方有一個 io.Writer, 會和這個產(chǎn)生沖突。
所以,在provider set中,應(yīng)該小心選擇返回類型。通常,會偏愛小型provider set。例如:一個provider set中只包含一個 由 wire.Bind 把 返回類型和接口聯(lián)系在一起的 provider 函數(shù)。避免使用較大的提供程序集可以降低應(yīng)用程序遇到?jīng)_突的可能性。舉例來說,假如你的go包為一個web服務(wù),提供一個客戶端。雖然將 *http.Client 的提供程序捆綁到您的庫客戶端的提供程序集中可能很誘人,但如果每個庫都這樣做,這樣做會導(dǎo)致沖突。相反,go包的提供者集應(yīng)該只包括 API 客戶端的提供者,并讓 *http.Client 成為提供者集的輸入。
Mocking
暫不涉及, 如果有興趣可以看一下原文