godi

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 17, 2019 License: MIT Imports: 3 Imported by: 0

README

Build Status codecov Go doc MIT License

GoDI

GoDI is a small dependency injection package. It provides simple API to create a dependency injection container and add non-singleton or singleton dependency makers to the container.

It is very useful for testing when you need to inject mocks for example.

Get started

Get GoDI

go get github.com/francoispqt/godi

Quick example:

package main

import (
	"io"

	"github.com/francoispqt/godi"
)

type SomeWriter struct{}

func (s *SomeWriter) Write(b []byte) (int, error) {
	return 0, nil
}

var myDependencyKey = struct{}{}

func main() {
    // create the DI container
    var DI = godi.New()
    // add a resolver
    DI.Bind(myDependencyKey, func(args ...interface{}) (interface{}, error) {
        return &SomeWriter{}, nil
    })
    // get an instance
    // will panic if dependency does not exist or resolver returns an error
    _ = DI.MustMake(myDependencyKey).(io.Writer)
}

New

New returns a new empty DI container.

var DI = godi.New()

*Container.Bind

Bind method adds a dependency maker to the container. The args passed to the Maker function are the args passed to the Make or MustMake method of the container.

DI.Bind(someKey, func(args ...interface{}) (interface{}, error) {
	return &SomeDependency{args[0].(string)}, nil
})
var r = DI.MustMake(someKey, "foo").(*SomeDependency)

*Container.BindSingleton

BindSingleton method adds a dependency maker to the container. The maker function is called only once, further calls will return the same results. The args passed to the Maker function are the args passed to the Make or MustMake method of the container.

DI.BindSingleton(someKey, func(args ...interface{}) (interface{}, error) {
	return &SomeDependency{args[0].(string)}, nil
})
var r = DI.MustMake(someKey, "foo").(*SomeDependency)
var r2 = DI.MustMake(someKey).(*SomeDependency)

fmt.Print(r == r2) // true

*Container.Make

Make method calls the dependency maker for the given key. It returns the result and an error. The error will be ErrDependencyNotFound if the dependency maker is not found in the container, else if the Maker returns an error it will be bubbled up. Arguments passed to Make after the key are passed to the found Maker function.

DI.Bind(someKey, func(args ...interface{}) (interface{}, error) {
    return &SomeDependency{
        k: args[0].(string), // "foo"
    }, nil
})
var r, err = DI.Make(someKey, "foo").(*SomeDependency)

*Container.MustMake

Make method calls the dependency maker for the given key. It behaves like Make but panics if an error is encountered. Arguments passed to Make after the key are passed to the found Maker function.

DI.Bind(someKey, func(args ...interface{}) (interface{}, error) {
    return &SomeDependency{
        k: args[0].(string), // "foo"
    }, nil
})
var r = DI.MustMake(someKey, "foo").(*SomeDependency)

Performance

Godi uses an atomic.Value to store a map[interface{}]Maker increasing performance significantly by providing a lock free mechanism even for singletons. Below are benchmarks when getting values, benchmarks are ran on a MacBook Pro 2,2 GHz Intel Core i7, 16GB 1600 MHz RAM:

goos: darwin
goarch: amd64
pkg: github.com/francoispqt/godi
BenchmarkMakeSingleton-8   	50000000	        36.9 ns/op	       0 B/op	       0 allocs/op
BenchmarkMake-8            	30000000	        45.1 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/francoispqt/godi	3.327s

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrDependencyNotFoundMsg = "Dependency '%v' does not exist"

ErrDependencyNotFoundMsg is the error message returned if the Maker is not found

Functions

func IsErrDependencyNotFound added in v0.1.0

func IsErrDependencyNotFound(err error) bool

IsErrDependencyNotFound returns whether the given error is a DependencNotFound error

Types

type Container

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

Container is the structure representing the dependency injecter

func New

func New() *Container

New returns a new instance of Container

func (*Container) Bind

func (di *Container) Bind(k interface{}, f func(args ...interface{}) (interface{}, error)) *Container

Bind adds a Maker for the key k to the Container's store.

func (*Container) BindSingleton

func (di *Container) BindSingleton(k interface{}, f func(args ...interface{}) (interface{}, error)) *Container

BindSingleton adds a singleton Maker for the key k to the Container's store. It will always return the same instance returned by the first call to the Maker function.

func (*Container) Make

func (di *Container) Make(k interface{}, args ...interface{}) (interface{}, error)

Make looks for the Maker function for the key k in the store and calls it with the given args it returns an ErrDependencyNotFound error if no Maker exist with the key k, else if the Maker returns a non nil error it will bubble up.

func (*Container) MustMake

func (di *Container) MustMake(k interface{}, args ...interface{}) interface{}

MustMake looks for the Maker function for the key k in the store and calls it with the given args It panics if an error happens.

type ErrDependencyNotFound

type ErrDependencyNotFound error

ErrDependencyNotFound is a custom error type for errors when dependency does not exist

func ErrDependencyNotFoundF added in v0.1.0

func ErrDependencyNotFoundF(dep interface{}) ErrDependencyNotFound

ErrDependencyNotFoundF returns an ErrDependencyNotFound error with the given dependency

type Injecter

type Injecter interface {
	Make(interface{}) (interface{}, bool)
	BindSingleton(interface{}, Maker)
	Bind(interface{}, Maker)
}

Injecter is the interface representing the dependency injecter

type Maker

type Maker func(...interface{}) (interface{}, error)

Maker is the function returning the instance of a dependency or an error it takes a list of arguments passed to the Container.Make method

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL