Documentation ¶
Overview ¶
Package di implements a dependency injection (DI) container.
Example ¶
package main import ( "fmt" "reflect" "github.com/go-ozzo/ozzo-di" ) type Bar interface { String() string } func test(bar Bar) { fmt.Println(bar.String()) } type Foo struct { s string } func (f *Foo) String() string { return f.s } type MyBar struct { Bar `inject:"true"` } func main() { // creating a DI container c := di.NewContainer() // register a Foo instance as the Bar interface type c.RegisterAs(&Foo{"hello"}, di.InterfaceOf((*Bar)(nil))) // &Foo{"hello"} will be injected as the Bar parameter for test() c.Call(test) // create a MyBar object and inject its Bar field bar := c.Make(reflect.TypeOf(&MyBar{})).(Bar) fmt.Println(bar.String() + "2") }
Output: hello hello2
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func InterfaceOf ¶
InterfaceOf is a helper method for turning an interface pointer into an interface reflection type. It is often used when calling RegisterAs() or Make() where you may want to specify an interface type. For example,
c := di.NewContainer() c.RegisterAs(Foo{}, di.InterfaceOf((*Bar)(nil))) foo := di.Make(di.InterfaceOf((*Bar)(nil)))
Types ¶
type Container ¶
type Container interface { // ParentContainer returns the parent container, if any. ParentContainer() Container // SetParentContainer sets the parent container. SetParentContainer(Container) // HasRegistered returns a value indicating whether the specified type has been registered before. HasRegistered(reflect.Type) bool // Unregister removes the specified type registration from the container Unregister(reflect.Type) // Register registers the specified value and associates it with the type of the value. Register(interface{}) // RegisterAs registers the specified value or type, and associates it with the specified type. // For example, // // c := di.NewContainer() // // register a Foo struct as the Bar interface // c.RegisterAs(&Foo{"abc"}, di.InterfaceOf((*Bar)(nil))) // // register the Foo type as the Bar interface // c.RegisterAs(reflect.TypeOf(&Foo{}), di.InterfaceOf((*Bar)(nil))) RegisterAs(interface{}, reflect.Type) // RegisterProvider registers the provider and associates it with the specified type. // When injecting or making a value for the type, the provider will be called and // its return value will be used as the value of the requested type. If shared is true, // the provider will only be called once, and its return value will be kept and used for // every injection request. RegisterProvider(p Provider, t reflect.Type, shared bool) // Call calls the specified function/method by injecting all its parameters. // The function/method result is returned as a slice. Call(interface{}) []interface{} // Inject injects the exported fields tagged with "inject" of the given struct. // Note that the struct should be passed as a pointer, or the fields won't be injected. Inject(interface{}) // Make returns an instance of the specified type. If the instance is a newly created struct, its fields // will be injected by calling Inject(). Note that Make does not always create a new instance. If the type // has been registered and is associated with a value, that value will be returned. Make(reflect.Type) interface{} }
Container is a dependency injection (DI) container based on type mapping.
Using Container involves two steps. First, register values, types, or providers with the types that should allow DI. Second, use one of the DI methods to achieve DI. For example,
import ( "reflect" "github.com/go-ozzo/ozzo-di" ) c := di.NewContainer() // Step 1: register values, types, providers // register the value Foo{"abc"} as type Foo c.Register(Foo{"abc"}) // register the value Foo{"abc"} as the interface Bar c.RegisterAs(Foo{"abc"}, di.InterfaceOf((*Bar)(nil))) // register the struct Foo as the interface Bar c.RegisterAs(reflect.TypeOf(Foo{}), di.InterfaceOf((*Bar)(nil))) // register a provider that returns a shared value as the interface Bar c.RegisterProvider(func(Container) reflect.Value { return reflect.ValueOf(&Foo{"xyz"}) }, di.InterfaceOf((*Bar)(nil)), true) // Step 2: dependency injection // use `inject` tag to indicate which fields can be injected type Tee struct { Foo `inject` bar Bar `inject` } // inject the fields of a struct t := Tee{} c.Inject(&t) // inject function parameters c.Call(func(bar Bar, foo Foo) {...}) // build a value of the specified type with injection t2 := c.Build(reflect.TypeOf(&Tee{})).(*Tee)
Note that when building an unregistered type, zero value will be returned. If the type is a struct, the zero value will be further injected by Inject() for those fields tagged with "inject".
func NewContainer ¶
func NewContainer() Container
NewContainer creates a new Dependency Injection (DI) container.