Documentation ¶
Overview ¶
Package di allows you to standardize and centralize the way objects are constructed in your application.
Example (HttpServer) ¶
This is example demonstrates how use dependency container for simple http application.
var builder, err = di.NewBuilder( di.BuilderOptions( di.Autowire((*BarController)(nil), di.As((*Controller)(nil))), // provide autowired type di.Autowire((*BazController)(nil), di.As((*Controller)(nil))), // provide autowired type ), di.BuilderOptions( di.Provide(NewServerMux), // provide constructor di.Provide(NewServer), // provide constructor ), ) if err != nil { fmt.Println() _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } // build container var container di.Container if container, err = builder.Build(); err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } // Call function with resolved dependencies _ = container.Call(func(srv *http.Server) { if srv == nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } }) fmt.Println("Listening...")
Output: Listening...
Example (Interfaces) ¶
This is example demonstrates Container.Resolve usage with aliases.
var builder, err = di.NewBuilder( // provide constructor di.Provide(NewBarController, di.As(new(Controller))), di.Provide(NewBazController, di.As(new(Controller))), ) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } var container di.Container if container, err = builder.Build(); err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } var controllers []Controller if err = container.Resolve(&controllers); err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } fmt.Println("resolved", len(controllers), "controllers")
Output: resolved 2 controllers
Example (OptionalFieldInjection) ¶
This is example demonstrates optional field injection.
type Foo struct { Bar *BarController Baz *BazController } var builder, err = di.NewBuilder( // provide autowired type with optional field Baz di.Autowire((*Foo)(nil), di.Constraint("Baz", di.Optional(true))), // provide constructor di.Provide(NewBarController), ) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } var container di.Container if container, err = builder.Build(); err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } err = container.Call(func(foo *Foo) error { if foo == nil { return errors.New("foo is nil") } if foo.Bar == nil { return errors.New("foo.Bar is nil") } if foo.Baz != nil { return errors.New("foo.Baz is not nil") } return nil }) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } fmt.Println("Looks like something is fine")
Output: Looks like something is fine
Example (Tags) ¶
This is example demonstrates Container.Has usage with modifiers.
var builder, err = di.NewBuilder( // provide constructor di.Provide(NewBarController, di.Tags{{ Name: "controller", }}), ) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } var container di.Container if container, err = builder.Build(); err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } if container.Has((*BarController)(nil), di.WithTags("controller")) { fmt.Println("container has *BarController with tag controller") } var c *BarController if err = container.Resolve(&c, di.WithTags("controller")); err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } if c != nil { fmt.Println("container resolved *BarController with tag controller") } err = container.Call(func(c *BarController) error { if c == nil { return errors.New("container call has nil *BarController") } fmt.Println("container call *BarController with tag controller") return nil }, di.Constraint(0, di.WithTags("controller"))) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) }
Output: container has *BarController with tag controller container resolved *BarController with tag controller container call *BarController with tag controller
Index ¶
- Variables
- func NewTypeError(typ reflect.Type, err error) error
- type AddOption
- type Arg
- type Args
- type AsOption
- type Builder
- type BuilderOption
- type ConstraintOption
- type Constructor
- type Container
- type Definition
- type Dependency
- type Function
- type Modifier
- type ProvideOption
- type Restriction
- type Tag
- type Tags
- type Type
- type TypeError
- type Value
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotPointerToInterface is error triggered when provided alias not pointer to interface. ErrNotPointerToInterface = errors.New("not pointer to interface") // ErrIsNil is error triggered when provided nil alias. ErrIsNil = errors.New("is nil") // ErrNotImplementInterface is error triggered when provided type not implement alias interface. ErrNotImplementInterface = errors.New("not implement interface") // ErrDoesNotExist triggered when type not present in container. ErrDoesNotExist = errors.New("does not exist") // ErrMustBeSliceOrPointer triggered when resolved in invalid target. ErrMustBeSliceOrPointer = errors.New("must be a slice or pointer") // ErrMultipleDefinitions triggered when type resolved in single instance, but container contain multiple types. ErrMultipleDefinitions = errors.New("multiple definitions") // ErrorMustBeFunction triggered when value not a function. ErrorMustBeFunction = errors.New("must be a function") // ErrInvalidConstructor is error triggered when constructor have invalid signature. ErrInvalidConstructor = compiler.ErrInvalidConstructor // ErrInvalidType is error triggered when provided invalid type. ErrInvalidType = compiler.ErrInvalidType // ErrInvalidValue is error triggered when provided invalid value. ErrInvalidValue = compiler.ErrInvalidValue )
Functions ¶
Types ¶
type AddOption ¶
type AddOption interface {
// contains filtered or unexported methods
}
AddOption is specified for Builder.Add method option interface.
func AddOptions ¶
AddOptions allow to organize logical groups of add options.
var builder = di.NewBuilder() builder.Add(di.AddOptions( di.As(new(io.Writer)), di.Tags{{ Name: "tag", }}, ))
type Builder ¶
type Builder interface { // Add provides value as is. // // The value argument must contain any value what you want, fre example: // - new(http.Server) // - *http.Server{} // - etc. // The options argument may be one of: // - di.Tags{} // - di.As() Add(value Value, options ...AddOption) error // Apply applies options to Builder. // The options argument may be one of: // - di.BuilderOptions() // - di.Add() // - di.Autowire() // - di.Provide() Apply(options ...BuilderOption) error // Autowire providers autowired type. // // The target argument must contain the wanted type, for example: // - (*http.Server)(nil) // - (*io.Writer)(nil) // - new(io.Writer) // - etc. // The options argument may be one of: // - di.As() // - di.Constraint() // - di.Tags{} // - di.Unshared() Autowire(target Type, options ...ProvideOption) error // Provide provides any constructor. // // The constructor argument must be a function with one of the following signatures: // - func New(constraints ...any) (value any) // - func New(constraints ...any) (value any, err error) // - func New(constraints ...any) (value any, closer func(){}) // - func New(constraints ...any) (value any, closer func(){}, err error) // The options argument may be one of: // - di.As() // - di.Constraint() // - di.Tags{} // - di.Unshared() Provide(constructor Constructor, options ...ProvideOption) error // Build is container build method. Build() (Container, error) // Definitions are build snapshot of definitions. Definitions() []Definition }
Builder must be used to create a Container. The Builder should be created with NewBuilder. Then you can provide any definition with various allowed methods and finally build the Container with the Build method.
func NewBuilder ¶
func NewBuilder(options ...BuilderOption) (_ Builder, err error)
NewBuilder is builder constructor.
type BuilderOption ¶
type BuilderOption interface {
// contains filtered or unexported methods
}
BuilderOption is specified for NewBuilder option interface.
func Add ¶
func Add(value Value, options ...AddOption) BuilderOption
Add is builder constructor option. This is a syntax sugar for builder constructor usage.
func Autowire ¶
func Autowire(value Type, options ...ProvideOption) BuilderOption
Autowire is builder constructor option. This is a syntax sugar for builder constructor usage.
func BuilderOptions ¶
func BuilderOptions(options ...BuilderOption) BuilderOption
BuilderOptions allow to organize logical groups of builder options.
var builder = di.NewBuilder( di.BuilderOptions( di.Provide(NewBarController), di.Provide(NewBazController), ), di.BuilderOptions( di.Provide(NewMuxServer), di.Provide(NewServer), ), )
func Provide ¶
func Provide(value Constructor, options ...ProvideOption) BuilderOption
Provide is builder constructor option. This is a syntax sugar for builder constructor usage.
type ConstraintOption ¶
type ConstraintOption interface { ProvideOption // contains filtered or unexported methods }
ConstraintOption is an option
func Constraint ¶
func Constraint(key any, restrictions ...Restriction) ConstraintOption
Constraint restricts the dependency resolving.
The key argument may be string, int or any other type
type Container ¶
type Container interface { // Call calls the function with resolved arguments. // // The fn argument must contain any function. If the function contains error in the last return type, // then Call will return that value as own return type value. // The options argument may be one of: // - di.Constraint() Call(fn Function, options ...ConstraintOption) (err error) // Close runs closers in reverse order that has been created. // // Any close function can return any error that stop the calling loop for all rest closers. Any close function // can return any error that stop the calling loop for all rest closers. That error will return in function // return type. Close() error // Has checks that type exists in container, if not it return false. // // The value argument must contain the wanted type, for example: // - (*http.Server)(nil) // - (*io.Writer)(nil) // - new(io.Writer) // - etc. // The modifiers argument may be one of: // - di.WithTags() Has(value Type, modifiers ...Modifier) (exist bool) // Resolve resolves type and fills target pointer. // // The target argument must contain reference to wanted variable. // The modifiers argument may be one of: // - di.WithTags() Resolve(target Value, modifiers ...Modifier) (err error) }
Container represents a dependency injection container. To create a container, you should use a builder.
type Definition ¶
type Definition interface { // ID is definition unique identificator getter. ID() int // Dependencies is definition type dependencies getter. Dependencies() []Dependency // Tags is definition tags getter. Tags() Tags // Type is definition type getter. Type() reflect.Type Unshared() bool }
Definition represent container definition.
type Dependency ¶
type Dependency struct { // Type is type of dependency. Type reflect.Type // Optional is optional flag. Optional bool // Definitions are list of matched definitions. Definitions []Definition }
Dependency represent definition dependency.
type Modifier ¶
type Modifier func(defs []Definition) []Definition
Modifier calling with definitions founded by type in container. Modifiers should use for filtering, sorting or any other modifications list of definitions before they should resolve.
func Filter ¶
func Filter(match func(def Definition) bool) Modifier
Filter filters the definitions the provided match function.
func Sort ¶
func Sort(less func(a, b Definition) bool) Modifier
Sort sorts the definitions the provided less function.
func WithoutTags ¶
WithoutTags filters out definitions with needed tags.
type ProvideOption ¶
type ProvideOption interface {
// contains filtered or unexported methods
}
ProvideOption is specified for Builder.Provide method option interface.
func ProvideOptions ¶
func ProvideOptions(options ...ProvideOption) ProvideOption
ProvideOptions allow to organize logical groups of provide options.
var builder = di.NewBuilder() builder.Provide(di.ProvideOptions( di.As(new(io.Writer)), di.Tags{{ Name: "tag", }}, ))
type Restriction ¶
type Restriction interface {
// contains filtered or unexported methods
}
Restriction is an option.
func Optional ¶
func Optional(v bool) Restriction
Optional set dependency optional or not, by default all dependencies are required.