从另一个文件访问在主函数中创建的运行时配置实例

I have a runtime config instance that I need in other parts of the app, but it can only be created in main(). Ideally I would like to avoid using global variables.

// main.go
type RuntimeConfig struct {
    db *DatabaseInstance
    app_name string
    ... etc ...
}

func main() {
    dbInstance = ConnectToDB(...args) // returns *DatabaseInstance
    runtimeConfig := *Config{
        dbInstance,
        "My app",
        ... etc ...
    }
}

// elsewhere.go
func SomeUtilityFuncThatNeedsRuntime(i int) int {
    runtime := GetRuntime() // imaginary, magical runtime getter
    db := runtime.DatabaseInstance
    appName := runtime.appName
    db.Save(appName, db, ...)
    return i + 1
}

Currently it's impossible to create anonymous util functions that could really benefit from having access to certain config variables. If the variables were basic types (like a string or int), I would probably just hard-code them in. However, a field like dbInstance requires a specific instance of a connected database.

This looks to me like a use case for the singleton pattern: your RuntimeConfig is a structure that should be initialized, exactly one instance of it should exist, and it should be possible to access it.

Create configuration package with private variable and public functions (pseudo code):

package configuration

type Configuration struct {

}

var config *Configuration = nil

func GetConfig() *Configuration {
    return config
}

func configLoad(filePath string) error {
    config = new(Configuration)

    // load your config from file, fill config structure

    return nil
}

func NewConfig(flags models.ConfigFlags) (*Configuration, error) {
    err := configLoad(flags.Flagconfiguration) // Path of config file.

    if err != nil {
        return nil, err
    }

    return config, nil
}

Then in your main.go initialize config:

func main() {
    config, err := configuration.NewConfig(FlagsParameters)
    // use this config variable in main package
}

In other packages use:

config := configuration.Config()

As an alternative, you can implement singleton pattern (but I like it less)

type Configuration struct {

}

var config *Configuration
var once sync.Once

func GetConfig() *Configuration {
    once.Do(func() {
        // init your config here. This code will executed once and thread safe
    })

    return config
}