hiboot: hidevops.io/hiboot/pkg/inject Index | Examples | Files

package inject

import "hidevops.io/hiboot/pkg/inject"

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.

This example shows that the dependency is injected through the constructor

Code:

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)
}

Index

Examples

Package Files

defaulttag.go doc.go inject.go injecttag.go tag.go valuetag.go

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")
)

func AddTag Uses

func AddTag(tag Tag)

AddTag add new tag

type BaseTag Uses

type BaseTag struct {
    // contains filtered or unexported fields
}

BaseTag is the base struct of tag

func (*BaseTag) Decode Uses

func (t *BaseTag) Decode(object reflect.Value, field reflect.StructField, property, tag string) (retVal interface{})

Decode no implementation for base tag

func (*BaseTag) Init Uses

func (t *BaseTag) Init(configurableFactory factory.InstantiateFactory)

Init init the tag

func (*BaseTag) IsSingleton Uses

func (t *BaseTag) IsSingleton() bool

IsSingleton check if it is Singleton

func (*BaseTag) ParseProperties Uses

func (t *BaseTag) ParseProperties(tag string) cmap.ConcurrentMap

ParseProperties parse properties

func (*BaseTag) Properties Uses

func (t *BaseTag) Properties() cmap.ConcurrentMap

Properties get properties

type Inject Uses

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 Uses

func NewInject(factory factory.InstantiateFactory) Inject

NewInject is the constructor of inject

type Tag Uses

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, tag string) (retVal interface{})
    // Properties get properties
    Properties() cmap.ConcurrentMap
    // IsSingleton check if it is Singleton
    IsSingleton() bool
}

Tag the interface of Tag

Package inject imports 12 packages (graph) and is imported by 2 packages. Updated 2019-05-20. Refresh now. Tools for package owners.