A dependency injection library that is focused on clean API and flexibility

Overview

GoDoc Go Report Card

Dependency injection

DI is a dependency injection library that is focused on clean API and flexibility. DI has two types of top-level abstractions: Container and Resolver. First one is responsible for accepting constructors and instances and creating abstraction bindings out of them. Second implements different instance resolution scenarios against one or more Containers.

Initially this library was heavily inspired by GoLobby Container but since then had a lot of backwards incompatible changes in structure, functionality and API. To install DI simply run in your project directory:

go get github.com/HnH/di

Container

type Container interface {
    Singleton(constructor interface{}, opts ...Option) error
    Instance(instance interface{}, name string) error
    Factory(constructor interface{}, opts ...Option) error
    ListBindings(reflect.Type) (map[string]Binding, error)
    Reset()
}

Singleton

Singleton() method requires a constructor which will return Implementation(s) of Abstraction(s). Constructor will be called once and returned Implementations(s) will later always bound to Abstraction(s) on resolution requests.

err = di.Singleton(func() (Abstraction, SecondAbstraction) {
    return Implementation, SecondImplementation
})

// Singleton may also accept naming option which means that returned Implementation will be available only under provided name
err = di.Singleton(func() (Abstraction) {
    return Implementation
}, di.WithName("customName"))

// Name can be provided for each of the Implementations if there are more than one
err = di.Singleton(func() (Abstraction, SecondAbstraction) {
    return Implementation, SecondImplementation
}, di.WithName("customName", "secondCustomName"))

// If there is only one Implementation returned you may give multiple aliases for it.
err = di.Singleton(func() (Abstraction) {
    return Implementation
}, di.WithName("customName", "secondCustomName"))

Factory

Factory() method requires a constructor which will return exactly one Implementation of exactly one Abstraction. Constructor will be called on each Abstraction resolution request.

err = di.Factory(func() (Abstraction) {
    return Implementation
})

// Factory also optionally accepts naming option which means that returned Implementation will be available only under provided name
err := di.Factory(func() (Abstraction) {
    return Implementation
}, di.WithName("customName"))

Resolver

type Resolver interface {
    With(instances ...interface{}) Resolver
    Resolve(receiver interface{}, opts ...Option) error
    Call(function interface{}, opts ...Option) error
    Fill(receiver interface{}) error
}

Resolve

Resolve() requires a receiver (pointer) of an Abstraction and fills it with appropriate Implementation.

var abs Abstraction
err = di.Resolve(&a)

// Resolution can be done with previously registered names as well
err = di.Resolve(&a, di.WithName("customName"))

Call

The Call() executes as function with resolved Implementation as a arguments.

err = di.Call(func(a Abstraction) {
    // `a` will be an implementation of the Abstraction
})

// returned values can be bound to variables by providing an option
var db Database
err = di.Call(func(a Abstraction) Database {
    return &MySQL{a}
}, di.WithReturn(&db))
// db == &MySQL{a}

Fill

The Fill() method takes a struct (pointer) and resolves its fields. The example below expresses how the Fill() method works.

err = di.Singleton(func() Mailer { return &someMailer{} })

err = di.Singleton(func() (Database, Database) {
    return &MySQL{}, &Redis{} 
}, di.WithName("data", "cache"))

type App struct {
    mailer Mailer    `di:"type"`
    data   Database  `di:"name"`
    cache  Database  `di:"name"`
    x int
}

myApp := App{}

err := container.Fill(&myApp)

// [Typed Bindings]
// `myApp.mailer` will be an implementation of the Mailer interface

// [Named Bindings]
// `myApp.data` will be a MySQL implementation of the Database interface
// `myApp.cache` will be a Redis implementation of the Database interface

// `myApp.x` will be ignored since it has no `di` tag

Alternatively map[string]Type or []Type can be provided. It will be filled with all available implementations of provided Type.

var list []Shape
container.Fill(&list)

// []Shape{&Rectangle{}, &Circle{}}

var list map[string]Shape
container.Fill(&list)

// map[string]Shape{"square": &Rectangle{}, "rounded": &Circle{}} 
Issues
  • Context propagation API

    Context propagation API

    type Context interface {
        Put(Container) Context
        Container() Container
        Resolver() Resolver
        Raw() context.Context
    }
    

    Context propagation is possible via di.Context abstraction. Quick example:

    var container = di.NewContainer()
    container.Implementation(newCircle())
    
    var (
        ctx = di.Ctx(context.Background).Put(container)
        shp Shape
    )
    
    err = ctx.Resolver().Resolve(&shp) // err == nil
    
    opened by HnH 2
  • Constructor interface. Binding WithFill() option.

    Constructor interface. Binding WithFill() option.

    Constructor implements a Construct() method which is called either after binding to container in case of singleton, either after factory method was called.

    opened by HnH 1
  • Global method API changes and global context

    Global method API changes and global context

    type Context interface {
    	SetContainer(Container) Context
    	Container() Container
    	SetResolver(Resolver) Context
    	Resolver() Resolver
    	Raw() context.Context
    }
    
    opened by HnH 1
  • Call() can return variables

    Call() can return variables

    var (
    	str string
    	db  Database
    )
    
    di.Call(func(s Shape) (string, Database, error) {
    	return "mysql", &MySQL{}, nil
    }, di.WithReturn(&str, &db))
    
    suite.Require().Equal("mysql", str)
    suite.Require().IsType(&MySQL{}, db)
    
    opened by HnH 0
  • Container and Resolver interfaces. Resolver can resolve against multiple containers.

    Container and Resolver interfaces. Resolver can resolve against multiple containers.

    func (suite *ResolverSuite) TestResolveMultiContainer() {
    	var (
    		localContainer   = di.NewContainer()
    		localResolver, _ = di.NewResolver(localContainer, suite.container)
    	)
    
    	suite.Require().NoError(suite.container.Singleton(newRectangle))
    	suite.Require().NoError(localContainer.Singleton(newMySQL))
    
    	var s Shape
    	suite.Require().NoError(suite.resolver.Resolve(&s))
    	suite.Require().IsType(&Rectangle{}, s)
    
    	var db Database
    	suite.Require().EqualError(suite.resolver.Resolve(&db), "di: no binding found for: di_test.Database")
    	suite.Require().Nil(db)
    
    	suite.Require().NoError(localResolver.Resolve(&db))
    	suite.Require().IsType(&MySQL{}, db)
    }
    
    opened by HnH 0
  • Container.Implementation() method API changes

    Container.Implementation() method API changes

    Implementation() receives ready instance and binds it to its REAL type, which means that declared abstract variable type (interface) is ignored.

    var circle Shape = newCircle()
    err = di.Implementation(circle)
    
    // will return error di: no binding found for: di_test.Shape
    var a Shape
    err = di.Resolve(&a)
    
    // will resolve circle
    var c *Circle
    err = di.Resolve(&a)
    
    // also naming options can be used as everywhere
    err = di.Implementation(circle, di.WithName("customName"))
    err = di.Resolve(&c, di.WithName("customName"))
    
    opened by HnH 0
  •  More informative errors

    More informative errors

    null

    opened by HnH 0
Releases(v1.2.3)
Owner
Sergey Treinis
Tech Lead / Golang software engineer
Sergey Treinis
Dependency Injection and Inversion of Control package

Linker Linker is Dependency Injection and Inversion of Control package. It supports the following features: Components registry Automatic dependency i

Logrange 32 May 6, 2021
An additive dependency injection container for Golang.

Alice Alice is an additive dependency injection container for Golang. Philosophy Design philosophy behind Alice: The application components should not

Minjie Zha 43 Sep 15, 2021
🛠 A full-featured dependency injection container for go programming language.

DI Dependency injection for Go programming language. Tutorial | Examples | Advanced features Dependency injection is one form of the broader technique

Goava 108 Nov 30, 2021
A reflection based dependency injection toolkit for Go.

⚒️ dig A reflection based dependency injection toolkit for Go. Good for: Powering an application framework, e.g. Fx. Resolving the object graph during

Uber Go 2.2k Dec 5, 2021
Go Dependency Injection Framework

Dingo Dependency injection for go Hello Dingo Dingo works very very similiar to Guice Basically one binds implementations/factories to interfaces, whi

Flamingo 115 Nov 24, 2021
A dependency injection based application framework for Go.

?? Fx An application framework for Go that: Makes dependency injection easy. Eliminates the need for global state and func init(). Installation We rec

Uber Go 2.4k Dec 5, 2021
Simple Dependency Injection Container

?? gocontainer gocontainer - Dependency Injection Container ?? ABOUT Contributors: Rafał Lorenz Want to contribute ? Feel free to send pull requests!

Rafał Lorenz 14 Dec 10, 2020
Strict Runtime Dependency Injection for Golang

wire Wire is runtime depedency injection/wiring for golang. It's designed to be strict to avoid your go application running without proper dependency

Muhammad Surya 34 Sep 28, 2021
Compile-time dependency injection for Go

Dihedral Dihedral is a compile-time injection framework for Go. Getting started > go get -u github.com/dimes/dihedral Create a type you want injected

null 76 Sep 4, 2020
Compile-time Dependency Injection for Go

Wire: Automated Initialization in Go Wire is a code generation tool that automates connecting components using dependency injection. Dependencies betw

Google 7k Dec 4, 2021
Generated dependency injection containers in go (golang)

Generation of dependency injection containers for go programs (golang). Dingo is a code generator. It generates dependency injection containers based

null 65 Dec 7, 2021
Golang PE injection on windows

GoPEInjection Golang PE injection on windows See: https://malwareunicorn.org/workshops/peinjection.html Based on Cryptowall's PE injection technique.

malwareunicorn 138 Nov 28, 2021
two scripts written in golang that will help you recognize dependency confusion.

two scripts written in golang that will help you recognize dependency confusion.

gv1_ 5 Oct 4, 2021
A builder 🔨 for binding evil program 😈 and normal document 🐣

GoFileBinder A builder ?? for binding evil program ?? and normal document ?? Usage Clone this repo and build GoFileBinder.go first, then start: ./GoFi

3ND 0 Nov 29, 2021
How we can run unit tests in parallel mode with failpoint injection taking effect and without injection race

This is a simple demo to show how we can run unit tests in parallel mode with failpoint injection taking effect and without injection race. The basic

amyangfei 1 Oct 31, 2021
GO2P is a P2P framework, designed with flexibility and simplicity in mind

go2p golang p2p framework By v-braun - viktor-braun.de. Description GO2P is a P2P framework, designed with flexibility and simplicity in mind. You can

Viktor Braun 85 Nov 7, 2021
CryptoPump is a cryptocurrency trading bot that focuses on high speed and flexibility

CryptoPump is a cryptocurrency trading bot that focuses on high speed and flexibility. The algorithms utilize Go Language and WebSockets to react in real-time to market movements based on Bollinger statistical analysis and pre-defined profit margins.

null 34 Nov 24, 2021
Gerasimos (Makis) Maropoulos 21.5k Dec 1, 2021
hiboot is a high performance web and cli application framework with dependency injection support

Hiboot - web/cli application framework About Hiboot is a cloud native web and cli application framework written in Go. Hiboot is not trying to reinven

hidevops.io 162 Nov 22, 2021
Simple and yet powerful Dependency Injection for Go

goioc/di: Dependency Injection Why DI in Go? Why IoC at all? I've been using Dependency Injection in Java for nearly 10 years via Spring Framework. I'

Go IoC 121 Nov 25, 2021
Dependency Injection and Inversion of Control package

Linker Linker is Dependency Injection and Inversion of Control package. It supports the following features: Components registry Automatic dependency i

Logrange 32 May 6, 2021
🦄🌈 YoyoGo is a simple, light and fast , dependency injection based micro-service framework written in Go.

???? YoyoGo is a simple, light and fast , dependency injection based micro-service framework written in Go. Support Nacos ,Consoul ,Etcd ,Eureka ,kubernetes.

YoyoFx 495 Dec 3, 2021
An additive dependency injection container for Golang.

Alice Alice is an additive dependency injection container for Golang. Philosophy Design philosophy behind Alice: The application components should not

Minjie Zha 43 Sep 15, 2021
🛠 A full-featured dependency injection container for go programming language.

DI Dependency injection for Go programming language. Tutorial | Examples | Advanced features Dependency injection is one form of the broader technique

Goava 108 Nov 30, 2021
A reflection based dependency injection toolkit for Go.

⚒️ dig A reflection based dependency injection toolkit for Go. Good for: Powering an application framework, e.g. Fx. Resolving the object graph during

Uber Go 2.2k Dec 5, 2021
Go Dependency Injection Framework

Dingo Dependency injection for go Hello Dingo Dingo works very very similiar to Guice Basically one binds implementations/factories to interfaces, whi

Flamingo 115 Nov 24, 2021
A dependency injection based application framework for Go.

?? Fx An application framework for Go that: Makes dependency injection easy. Eliminates the need for global state and func init(). Installation We rec

Uber Go 2.4k Dec 5, 2021
Simple Dependency Injection Container

?? gocontainer gocontainer - Dependency Injection Container ?? ABOUT Contributors: Rafał Lorenz Want to contribute ? Feel free to send pull requests!

Rafał Lorenz 14 Dec 10, 2020
Strict Runtime Dependency Injection for Golang

wire Wire is runtime depedency injection/wiring for golang. It's designed to be strict to avoid your go application running without proper dependency

Muhammad Surya 34 Sep 28, 2021