go - 在 Go Wire 注入(inject)中使用单例模式

标签 go dependency-injection

我有一段代码用于从文件加载配置并将其解析为结构,我经常使用此配置,因此我在方法参数中传递它。现在,随着我的方法参数的增加,我正在研究依赖注入(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/

相关文章:

go - Switch case 语句落空为 default

go get -> 无法下载,/home/azhukov/go 是 GOROOT,不是 GOPATH

oracle - Go lang 连接到 Oracle 9i(使用 go-oci8)

go - 如何在Go中使用多个空白标识符?

c# - DependencyInjection 是否支持自动注册服务?

c# - DependencyResolver.Current.GetService 总是返回 null

dictionary - 使用 map [字符串]接口(interface){} :

c# - TinyIoC - 接口(interface)的多种实现

c# - 简易喷油器 : Registering a type with constructor argument that's based on its parent

java - 如何在 Eclipse RCP 3.x 中提供依赖注入(inject)?