我有一段代码用于从文件加载配置并将其解析为结构,我经常使用此配置,因此我在方法参数中传递它。现在,随着我的方法参数的增加,我正在研究依赖注入(inject),并已与 wire 达成一致。
现在我已经创建了一个提供程序来加载配置和一个注入(inject)器来提供配置结构。然而,每次我调用注入(inject)时,我的文件都会被再次读取,我希望文件被读取一次,并根据需要多次提供注入(inject),而无需任何额外加载。
这是我的 vendor :
// ProvideConfig config provider ...
func ProvideConfig() *config.FileConfig {
var cfp string
flag.StringVar(&cfp, "config", "config.json", "absolute path")
flag.Parse()
return config.Loadconfig(cfp)
}
注入(inject)器:
// GetConfig injector ...
func GetConfig() ConfigResource {
wire.Build(ProvideConfig, NewConfigResource)
return ConfigResource{}
}
现在当我打电话时:
injection.GetConfig()
我看到 ProvideConfig 总是被调用。我可以检查 provide config 方法以确定配置是否已经加载,我不确定是否有更好的方法,比如内置在线路中的单个实例加载器。我尝试查看文档,但找不到任何相关内容。
最佳答案
据我所知,wire
中没有内置方法来指定提供者是单例/只能调用一次。
这是通过使用 sync.Once
在 Go 中以通常的方式完成的。您的提供者函数可以是一个闭包,它使用 sync.Once.Do
仅执行一次昂贵的操作。这在 Go 中是惯用的,并且不需要每个想要提供“单一”加载的库的任何特殊规定。
这是一个没有电线的例子:
type Value struct {
id int
msg string
}
type ValueProvider func() *Value
// consumer takes a function that provides a new *Value and consumes
// the *Value provided by it.
func consumer(vp ValueProvider) {
v := vp()
fmt.Printf("Consuming %+v\n", *v)
}
// MakeSingleLoader returns a ValueProvider that creates a value once using an
// expensive operation, and then keeps returning the same value.
func MakeSingleLoader() ValueProvider {
var v *Value
var once sync.Once
return func() *Value {
once.Do(func() {
v = ExpensiveOperation()
})
return v
}
}
// ExpensiveOperation emulates an expensive operation that can take a while
// to run.
func ExpensiveOperation() *Value {
return &Value{id: 1, msg: "hello"}
}
func main() {
sl := MakeSingleLoader()
consumer(sl)
consumer(sl)
consumer(sl)
}
如果您同意“单例”值是全局值,则可以稍微简化此代码。否则,它只会调用 ExpensiveOperation
一次,并将值缓存在一个本地,在 MakeSingleLoader
之外无法访问。
关于go - 在 Go Wire 注入(inject)中使用单例模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67334017/