Need help with goldi?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

126 Stars 8 Forks MIT License 175 Commits 2 Opened issues


Goldi: lazy dependency injection framework for go.

Services available


Need anything else?

Contributors list

# 108,132
138 commits
# 63,057
16 commits

Build Status Coverage Status GoDoc license Join the chat at

Goldi: lazy dependency injection framework for go.

This library enables you to build your applications based on a dependency injection container. It helps to make your code modular, flexible and ensures that you can reuse components easily.

If you are familiar with the Symfony dependency injection framework you should feel at home here.

The goldi API


go get
to get the goldi API:
$ go get

No additional dependencies are required to use the library. The full documentation is available at It is almost complete and includes a lot of examples on how to use goldi.


First you need to define the types you are going to use later

import (

// create a new container when your application loads registry := goldi.NewTypeRegistry() config := map[string]interface{}{ "some_parameter": "Hello World", "timeout": 42.7, } container := goldi.NewContainer(registry, config)

// now define the types you want to build using the di container // you can use simple structs container.RegisterType("logger", &SimpleLogger{}) container.RegisterType("api.geo.client", new(GeoClient), "")

// you can also use factory functions and parameters container.RegisterType("acme_corp.mailer", NewAwesomeMailer, "first argument", "%some_parameter%")

// dynamic or static parameters and references to other services can be used as arguments container.RegisterType("renderer", NewRenderer, "@logger")

// closures and functions are also possible container.Register("http_handler", goldi.NewFuncType(func(w http.ResponseWriter, r *http.Request) { // do amazing stuff }))

// once you are done registering all your types you should probably validate the container validator := validation.NewContainerValidator() validator.MustValidate(container) // will panic, use validator.Validate to get the error

// whoever has access to the container can request these types now logger := container.MustGet("logger").(LoggerInterface) logger.DoStuff("...")

// in the tests you might want to exchange the registered types with mocks or other implementations container.RegisterType("logger", NewNullLogger)

// if you already have an instance you want to be used you can inject it directly myLogger := NewNullLogger() container.InjectInstance("logger", myLogger)

The types are build lazily. This means that the

will only be created when you ask the container for it the first time. Also all built types are singletons. This means that if you call
two times you will always get the same instance of whatever
stands for.

More detailed usage examples and a list of features will be available eventually.

The goldigen binary

If you are used to frameworks like Symfony you might want to define your types in an easy to maintain yaml file. You can do this using goldigen.


go get
to install the goldigen binary:
$ go get
Goldigen depends on (LGPLv3) for the parsing of the yaml files and Kingpin (MIT licensed) for the command line flag parsing.

You then need to define your types like this:

        type: SimpleLogger

    type: Client
    factory: NewDefaultClient
        - "%client_base_url%"   # As in the API you can use parameters here
        - "@logger"             # You can also reference other types 

    type: Clock
    factory: NewSystemClock

    func:    HandleHTTP         # You can register functions as types using the "func" keyword

Now you have your type configuration file you can use goldigen like this:

$ goldigen --in config/types.yml --out lib/dependency_injection.go

This will generate the following output and write it to

//go:generate goldigen --in "../config/types.yml" --out "dependency_injection.go" --package --function RegisterTypes --overwrite --nointeraction
package lib

import ( "" "" "" )

// RegisterTypes registers all types that have been defined in the file "../config/types.yml" // // DO NOT EDIT THIS FILE: it has been generated by goldigen v0.9.9. // It is however good practice to put this file under version control. // See for what is going on here. func RegisterTypes(types goldi.TypeRegistry) { types.RegisterAll(map[string]goldi.TypeFactory{ "http_handler": goldi.NewFuncType(example.HandleHTTP), "logger": goldi.NewStructType(new(SimpleLogger)), "my_fancy.client": goldi.NewType(NewDefaultClient, "%client_base_url%", "@logger"), "time.clock": goldi.NewType(mytime.NewSystemClock), }) }

As you might have noticed goldigen has created a go generate comment for you. Next time you want to update

you can simply run
go generate

Goldigen tries its best to determine the output files package by looking into your

. In certain situations this might not be enough so you can set a package explicitly using the

For a full list of goldigens flags and parameters try:

$ goldigen --help

Now all you need to to is to create the di container as you would just using the goldi API and then somewhere in the bootstrapping of your application call.


If you have a serious error in your type registration (like returning more than one result from your type factory method) goldi defers error handling by return an invalid type. You can check for invalid types with the

or by using
directly. Using the
is always the preferred option since it will check for a wide variety of bad configurations like undefined parameters or circular type dependencies.

Note that using goldigen is completely optional. If you do not like the idea of having an extra build step for your application just use goldis API directly.


Goldi is licensed under the the MIT license. Please see the LICENSE file for details.


Any contributions are always welcome (use pull requests). For each pull request make sure that you covered your changes and additions with ginkgo tests. If you are unsure how to write those just drop me a message.

Please keep in mind that I might not always be able to respond immediately but I usually try to react within the week ☺.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.