Documentation
¶
Overview ¶
Package dig is the dig: Dependency Injection Framework for Go.
package dig provides an opinionated way of resolving object dependencies.
Status ¶
BETA. Expect potential API changes.
Container ¶
package dig exposes type Container as an object capable of resolving a directional dependency graph.
To create one:
import "go.uber.org/dig" func main() { c := dig.New() // dig container `c` is ready to use! }
**All objects in the container are treated as a singletons**, meaning there can be only one object in the graph of a given type.
There are plans to expand the API to support multiple objects of the same type in the container, but for time being consider using a factory pattern.
Provide ¶
The Provide method adds a constructor of an object (or objects), to the container. A constructor can be a function returning any number of objects and, optionally, an error.
Each argument to the constructor is registered as a **dependency** in the graph.
type A struct {} type B struct {} type C struct {} c := dig.New() constructor := func (*A, *B) *C { // At this point, *A and *B have been resolved through the graph // and can be used to provide an object of type *C return &C{} } err := c.Provide(constructor) // dig container is now able to provide *C to any constructor. // // However, note that in the current example *A and *B // have not been provided, meaning that the resolution of type // *C will result in an error, because types *A and *B can not // be instantiated.
Advanced Provide ¶
// TODO: docs on dig.In usage // TODO: docs on dig.Out usage
Invoke ¶
The Invoke API is the flip side of Provide and used to retrieve types from the container.
Invoke looks through the graph and resolves all the constructor parameters for execution.
In order to successfully use use Invoke, the function must meet the following criteria:
• Input to the Invoke must be a function
• All arguments to the function must be types in the container
• If an error is returned from an invoked function, it will be propagated to the caller
Here is a fully working somewhat real-world Invoke example:
package main import ( "go.uber.org/config" "go.uber.org/dig" "go.uber.org/zap" ) func main() { c := dig.New() // Provide configuration object c.Provide(func() config.Provider { return config.NewYAMLProviderFromBytes([]byte("tag: Hello, world!")) }) // Provide a zap logger which relies on configuration c.Provide(func(cfg config.Provider) (*zap.Logger, error) { l, err := zap.NewDevelopment() if err != nil { return nil, err } return l.With(zap.String("iconic phrase", cfg.Get("tag").AsString())), nil }) // Invoke a function that requires a zap logger, which in turn requires config c.Invoke(func(l *zap.Logger) { l.Info("You've been invoked") // Logger output: // INFO You've been invoked {"iconic phrase": "Hello, world!"} // // As we can see, Invoke caused the Logger to be created, which in turn // required the configuration to be created. }) }
Index ¶
Constants ¶
const Version = "1.0.0-rc1"
Version of the library
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Container ¶
type Container struct {
// contains filtered or unexported fields
}
A Container is a directed, acyclic graph of dependencies. Dependencies are constructed on-demand and returned from a cache thereafter, so they're effectively singletons.
func (*Container) Invoke ¶
Invoke runs a function, supplying its arguments from the Container. If the function's last return value is an error, that error is propagated to the caller. All other returned values (if any) are ignored.
Passing anything other than a function to Invoke returns an error immediately.
func (*Container) Provide ¶
Provide teaches the Container how to construct one or more new types. It accepts either a constructor function or an already-constructed object.
Any function passed to Provide is assumed to be a constructor. Constructors can take any number of parameters, which will be supplied by the Container on demand. They must return at least one non-error value, all of which are then available in the Container. If the last returned value is an error, the Container inspects it to determine whether the constructor succeeded or failed. Regardless of position, returned errors are never put into the Container's dependency graph.
All non-functions (including structs, pointers, Go's built-in collections, and primitive types like ints) are inserted into the Container as-is.
type In ¶
type In struct {
// contains filtered or unexported fields
}
In is an embeddable object that signals to dig that the struct should be treated differently. Instead of itself becoming an object in the graph, memebers of the struct are inserted into the graph.
Tags on those memebers control their behavior. For example,
type Input struct { dig.In S *Something T *Thingy `optional:"true"` }