Documentation ¶
Overview ¶
Package inject implements dependency injection.
Dependency injection with the struct tag `inject:""` or the constructor.
Dependency injection in Go ¶
Dependency injection is a concept valid for any programming language. The general concept behind dependency injection is called Inversion of Control. According to this concept a struct should not configure its dependencies statically but should be configured from the outside.
Dependency Injection design pattern allows us to remove the hard-coded dependencies and make our application loosely coupled, extendable and maintainable.
Dependency Injection is the idea that your components (usually structs in go) should receive their dependencies when being created.This runs counter to the associated anti-pattern of components building their own dependencies during initialization.
A Go struct has a dependency on another struct, if it uses an instance of this struct. We call this a struct dependency. For example, a struct which accesses a user controller has a dependency on user service struct.
Ideally Go struct should be as independent as possible from other Go struct. This increases the possibility of reusing these struct and to be able to test them independently from other struct.
Dependency injection by constructor ¶
To use dependency injection, first, you need to register the dependency in init func by calling app.Component(newFooService), newFoo is the constructor of the dependency.
// dependency foo type FooService struct { } // FooService constructor func newFooService() *FooService { return &Foo{} } func init() { app.Component(newFooService) } // the consumer barController that depends on FooService type barController { fooService *FooService } // the consumer's constructor newBarController that inject the instance of FooService func newBarController(fooService *FooService) *barController { return &barService{ fooService: fooService, } }
Auto Configuration ¶
Auto Configuration is another cool feature that comes out of the box with Hiboot, for more details, please see https://godoc.org/hidevops.io/hiboot/pkg/starter
Example ¶
The following example shows a struct which has no hard dependencies.
Example ¶
This example shows that the dependency is injected through the constructor
package main import ( "hidevops.io/hiboot/pkg/app" "hidevops.io/hiboot/pkg/app/web" "hidevops.io/hiboot/pkg/at" ) // This example shows that the dependency is injected through the constructor func main() { web.NewApplication().Run() } // HelloService is a simple service interface, with interface, we can mock a fake service in unit test type HelloService interface { SayHello(name string) string } type helloServiceImpl struct { } func init() { // Register Rest Controller through constructor newHelloController // Register Service through constructor newHelloService app.Register(newHelloController, newHelloService) } // please note that the return type name of the constructor HelloService, // hiboot will instantiate a instance named helloService for dependency injection func newHelloService() HelloService { return &helloServiceImpl{} } // SayHello is a service method implementation func (s *helloServiceImpl) SayHello(name string) string { return "Hello" + name } // PATH: /login type helloController struct { at.RestController helloService HelloService } // newHelloController inject helloService through the argument helloService HelloService on constructor func newHelloController(helloService HelloService) *helloController { return &helloController{ helloService: helloService, } } // Get / // The first word of method name is the http method GET func (c *helloController) Get(name string) string { return c.helloService.SayHello(name) }
Output:
Index ¶
- Variables
- func AddTag(tag Tag)
- type BaseTag
- func (t *BaseTag) Decode(object reflect.Value, field reflect.StructField, property string) (retVal interface{})
- func (t *BaseTag) Init(configurableFactory factory.InstantiateFactory)
- func (t *BaseTag) IsSingleton() bool
- func (t *BaseTag) ParseProperties(tag string) cmap.ConcurrentMap
- func (t *BaseTag) Properties() cmap.ConcurrentMap
- type Inject
- type Tag
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotImplemented the interface is not implemented ErrNotImplemented = errors.New("[inject] interface is not implemented") // ErrInvalidObject the object is invalid ErrInvalidObject = errors.New("[inject] invalid object") // ErrInvalidTagName the tag name is invalid ErrInvalidTagName = errors.New("[inject] invalid tag name, e.g. exampleTag") // ErrSystemConfiguration system is not configured ErrSystemConfiguration = errors.New("[inject] system is not configured") // ErrInvalidFunc the function is invalid ErrInvalidFunc = errors.New("[inject] invalid func") // ErrInvalidMethod the function is invalid ErrInvalidMethod = errors.New("[inject] invalid method") // ErrFactoryIsNil factory is invalid ErrFactoryIsNil = errors.New("[inject] factory is nil") )
Functions ¶
Types ¶
type BaseTag ¶ added in v0.3.0
type BaseTag struct {
// contains filtered or unexported fields
}
BaseTag is the base struct of tag
func (*BaseTag) Decode ¶ added in v0.3.0
func (t *BaseTag) Decode(object reflect.Value, field reflect.StructField, property string) (retVal interface{})
Decode no implementation for base tag
func (*BaseTag) Init ¶ added in v0.5.0
func (t *BaseTag) Init(configurableFactory factory.InstantiateFactory)
Init init the tag
func (*BaseTag) IsSingleton ¶ added in v0.3.0
IsSingleton check if it is Singleton
func (*BaseTag) ParseProperties ¶ added in v0.3.0
func (t *BaseTag) ParseProperties(tag string) cmap.ConcurrentMap
ParseProperties parse properties
func (*BaseTag) Properties ¶ added in v0.3.0
func (t *BaseTag) Properties() cmap.ConcurrentMap
Properties get properties
type Inject ¶ added in v0.11.0
type Inject interface { DefaultValue(object interface{}) error IntoObject(object interface{}) error IntoObjectValue(object reflect.Value, property string, tags ...Tag) error IntoMethod(object interface{}, m interface{}) (retVal interface{}, err error) IntoFunc(object interface{}) (retVal interface{}, err error) }
Inject is the interface for inject tag
func NewInject ¶ added in v0.11.0
func NewInject(factory factory.InstantiateFactory) Inject
NewInject is the constructor of inject
type Tag ¶ added in v0.3.0
type Tag interface { // Init init tag Init(configurableFactory factory.InstantiateFactory) // Decode parse tag and do dependency injection Decode(object reflect.Value, field reflect.StructField, property string) (retVal interface{}) // Properties get properties Properties() cmap.ConcurrentMap // IsSingleton check if it is Singleton IsSingleton() bool }
Tag the interface of Tag