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") // ErrCycleDetected is error triggered when was cycle detected. ErrCycleDetected = errors.New("cycle detected") // 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.