如何使用Google Wire注入Go语言包级变量?
为Google Wire注入包级变量的可行方案
方案一:创建包级变量初始化Provider
在目标包(ABC)中定义专门的初始化函数,将其作为Wire的Provider纳入依赖注入流程,由Wire生成的代码自动调用完成包级变量赋值。
示例代码:
ABC包代码(abc/abc.go)
package abc type B struct{} type C struct{} // 包级变量 var ( b *B c *C ) // InitPackageVars 接收依赖实例并赋值给包级变量 func InitPackageVars(bInst *B, cInst *C) { b = bInst c = cInst } // 原有的构造函数和结构体 type A struct { B *B } func NewA(b *B) *A { return &A{B: b} } // B和C的构造函数 func NewB() *B { return &B{} } func NewC() *C { return &C{} }
Wire注入配置(wire/wire.go)
// +build wireinject package wire import ( "your/project/path/abc" "github.com/google/wire" ) // InitApp 作为注入入口,完成所有依赖初始化与包级变量赋值 func InitApp() (*abc.A, error) { wire.Build( abc.NewB, abc.NewC, abc.InitPackageVars, // 注入流程中自动调用初始化包级变量 abc.NewA, ) return nil, nil }
运行wire命令生成代码后,调用InitApp()时,Wire会先构建*B和*C实例,再通过InitPackageVars将实例赋值给包级变量,最后完成*A的构建。
方案二:通过Setter函数封装包级变量赋值
如果希望隐藏直接赋值包级变量的逻辑,可以为变量定义Setter方法,将Setter作为Provider纳入Wire依赖图。
示例代码(ABC包修改后):
package abc type B struct{} type C struct{} var ( b *B c *C ) // SetB 设置包级变量b func SetB(bInst *B) { b = bInst } // SetC 设置包级变量c func SetC(cInst *C) { c = cInst } // 其余构造函数和结构体代码同方案一...
对应的Wire配置:
// +build wireinject package wire import ( "your/project/path/abc" "github.com/google/wire" ) func InitApp() (*abc.A, error) { wire.Build( abc.NewB, abc.NewC, wire.Bind(new(func(*B)), new(abc.SetB)), // 绑定SetB为*B的消费者 wire.Bind(new(func(*C)), new(abc.SetC)), // 绑定SetC为*C的消费者 abc.NewA, ) return nil, nil }
注意事项
- 包级变量属于全局状态,使用时需谨慎,避免因全局依赖导致代码耦合度升高、测试难度增加。
- 确保初始化逻辑仅在应用启动阶段执行一次,若涉及并发场景,需为包级变量添加同步机制避免竞态问题。
内容的提问来源于stack exchange,提问作者vuhoanghiep1993
相关产品推荐
相关产品推荐

