Go Dependency Injection Framework

Dingo

Go Report Card GoDoc Build Status

Dependency injection for go

Hello Dingo

Dingo works very very similiar to Guice

Basically one binds implementations/factories to interfaces, which are then resolved by Dingo.

Given that Dingo's idea is based on Guice we use similar examples in this documentation:

The following example shows a BillingService with two injected dependencies. Please note that Go's nature does not allow contructors, and does not allow decorations/annotations beside struct-tags, thus, we only use struct tags (and later arguments for providers).

Also Go does not have a way to reference types (like Java's Something.class) we use either pointers or nil and cast it to a pointer to the interface we want to specify: (*Something)(nil). Dingo then knowns how to dereference it properly and derive the correct type Something. This is not necessary for structs, where we can just use the null value via Something{}.

See the example folder for a complete example.

package example

type BillingService struct {
	processor CreditCardProcessor
	transactionLog TransactionLog
}

func (billingservice *BillingService) Inject(processor CreditCardProcessor, transactionLog TransactionLog) {
	billingservice.processor = processor
	billingservice.transactionLog = transactionLog
}

func (billingservice *BillingService) ChargeOrder(order PizzaOrder, creditCard CreditCard) Receipt {
	// ...
}

We want the BillingService to get certain dependencies, and configure this in a BillingModule which implements dingo.Module:

package example

type BillingModule struct {}

func (module *BillingModule) Configure(injector *dingo.Injector) {
	// This tells Dingo that whenever it sees a dependency on a TransactionLog, 
	// it should satisfy the dependency using a DatabaseTransactionLog. 
	injector.Bind(new(TransactionLog)).To(DatabaseTransactionLog{})

	// Similarly, this binding tells Dingo that when CreditCardProcessor is used in
	// a dependency, that should be satisfied with a PaypalCreditCardProcessor. 
	injector.Bind(new(CreditCardProcessor)).To(PaypalCreditCardProcessor{})
}

Requesting injection

Every instance that is created through the container can use injection.

Dingo supports two ways of requesting dependencies that should be injected:

  • usage of struct tags to allow structs to request injection into fields. This should be used for public fields.
  • implement a public Inject(...) method to request injections of private fields. Dingo calls this method automatically and passes the requested injections.

For every requested injection (unless an exception applies) Dingo does the following:

  • Is there a binding? If so: delegate to the binding
    • Is the binding in a certain scope (Singleton)? If so, delegate to scope (might result in a new loop)
    • Binding is bound to an instance: inject instance
    • Binding is bound to a provider: call provider
    • Binding is bound to a type: request injection of this type (might return in a new loop to resolve the binding)
  • No binding? Try to create (only possible for concrete types, not interfaces or functions)

Example: Here is another example using the Inject method for private fields

package example

type MyBillingService struct {
	processor CreditCardProcessor
	accountId string
}

func (m *MyBillingService) Inject(
	processor CreditCardProcessor,
	config *struct {
		AccountId  string `inject:"config:myModule.myBillingService.accountId"`
	},
) {
	m.processor = CreditCardProcessor
	m.accountId = config.AccountId
}

Usage of Providers

Dingo allows to request the injection of provider instead of instances. A "Provider" for dingo is a function that return a new Instance of a certain type.

package example

type pizzaProvider func() Pizza

func (s *Service) Inject(provider pizzaProvider) {
	s.provider = provider
}

If there is no concrete binding to the type func() Pizza, then instead of constructing one Pizza instance Dingo will create a new function which, on every call, will return a new instance of Pizza.

The type must be of func() T, a function without any arguments which returns a type, which again has a binding.

This allows to lazily create new objects whenever needed, instead of requesting the Dingo injector itself.

You can use Providers and call them to always get a new instance. Dingo will provide you with an automatic implementation of a Provider if you did not bind a specific one.

Use a Provider instead of requesting the Type directly when:

  • for lazy binding
  • if you need new instances on demand
  • In general it is best practice to use a Provider for everything that has a state that might be changed. This way you will avoid undesired side effects. That is especially important for dependencies in objects that are shared between requests - for example a controller!

Example 1: This is the only code required to request a Provider as a dependency:

MyStructProvider func() *MyStruct
MyStruct         struct {}

MyService struct {
	MyStructProvider MyStructProvider `inject:""`
}

Example 2:

package example

func createSomething(thing SomethingElse) Something{
	return &MySomething{somethingElse: thing}
}

injector.Bind(new(Something)).ToProvider(createSomething)

type somethingProvider func() Something

type service struct {
	provider somethingProvider
}

will essentially call createSomething(new(SomethingElse)) everytime SomethingProvider() is called, passing the resulting instance thru the injection to finalize uninjected fields.

Optional injection

An injection struct tag can be marked as optional by adding the suffix ,optional to it. This means that for interfaces, slices, pointers etc where dingo can not resolve a concrete type, the nil-type is injected.

You can check via if my.Prop == nil if this is nil.

Bindings

Dingo uses bindings to express dependencies resolutions, and will panic if there is more than one binding for a type with the same name (or unnamed), unless you use multibindings.

Bind

Bind creates a new binding, and tells Dingo how to resolve the type when it encounters a request for this type. Bindings can chain, but need to implement the correct interfaces.

injector.Bind(new(Something))

AnnotatedWith

By default a binding is unnamend, and thus requested with the inject:"" tag.

However you can name bindings to have more concrete kinds of it. Using AnnotatedWith you can specify the name:

injector.Bind((*Something)(nil)).AnnotatedWith("myAnnotation")

It is requested via the inject:"myAnnotation" tag. For example:

struct {
	PaypalPaymentProcessor PaymentProcessor `inject:"Paypal"`
}

To

To defines which type should be created when this type is requested. This can be an Interface which implements to one it is bound to, or a concrete type. The type is then created via reflect.New.

injector.Bind(new(Something)).To(MyType{})

ToProvider

If you want a factory to create your types then you rather use ToProvider instead of To.

ToProvider is a function which returns an instance (which again will go thru Dingo to fill dependencies).

Also the provider can request arguments from Dingo which are necessary to construct the bounded type. If you need named arguments (e.g. a string instance annotated with a configuration value) you need to request an instance of an object with these annotations, because Go does not allow to pass any meta-information on function arguments.

func MyTypeProvider(se SomethingElse) *MyType {
	return &MyType{
		Special: se.DoSomething(),
	}
}

injector.Bind(new(Something)).ToProvider(MyTypeProvider)

This example will make Dingo call MyTypeProvider and pass in an instance of SomethingElse as it's first argument, then take the result of *MyType as the value for Something.

ToProvider takes precedence over To.

ToInstance

For situations where you have one, and only one, concrete instance you can use ToInstance to bind something to the concrete instance. This is not the same as a Singleton! (Even though the resuting behaviour is very similar.)

var myInstance = new(MyType)
myInstance.Connect(somewhere)
injector.Bind(new(Something)).ToInstance(myInstance)

You can also bind an instance it to a struct obviously, not only to interfaces.

ToInstance takes precedence over both To and ToProvider.

In (Singleton scopes)

If really necessary it is possible to use singletons

.AsEagerSingleton() binds as a singleton, and loads it when the application is initialized
.In(dingo.Singleton) makes it a global singleton
.In(dingo.ChildSingleton) makes it a singleton limited to the current injector

In allows us to bind in a scope, making the created instances scoped in a certain way.

Currently Dingo only allows to bind to dingo.Singleton and dingo.ChildSingleton.

injector.Bind(new(Something)).In(dingo.Singleton).To(MyType{})

dingo.Singleton

The dingo.Singleton scope makes sure a dependency is only resolved once, and the result is reused. Because the Singleton needs synchronisation for types over multiple concurrent goroutines and make sure that a Singleton is only created once, the initial creation can be costly and also the injection of a Singleton is always taking more resources than creation of an immutable new object.

The synchronisation is done on multiple levels, a first test tries to find the singleton, if that is not possible a lock-mechanism via a scoped Mutex takes care of delegating the concrete creation to one goroutine via a scope+type specific Mutex which then generates the Singleton and makes it available to other currently waiting injection requests, as well as future injection requests.

By default it is advised to not use Singletons whenever possible, and rather use immutable objects you inject whenever you need them.

dingo.ChildSingleton

The ChildSingleton is just another Singleton (actually of the same type), but dingo will create a new one for every derived child injector.

This allows frameworks like Flamingo to distinguish at a root level between singleton scopes, e.g. for multi-page setups where we need a wide scope for routers.

Since ChildSingleton is very similar to Singleton you should only use it with care.

AsEagerSingleton

Singleton creation is always costly due to synchronisation overhead, therefore Dingo bindings allow to mark a binding AsEagerSingleton.

This makes sure the Singleton is created as soon as possible, before the rest of the Application runs. AsEagerSingleton implies In(dingo.Singleton).

injector.Bind(new(Something)).To(MyType{}).AsEagerSingleton()

It is also possible to bind a concrete type without To:

injector.Bind(MyType{}).AsEagerSingleton()

Binding this type as an eager singleton inject the singleton instance whenever MyType is requested. MyType is a concrete type (struct) here, so we can use this mechanism to create an instance explicitly before the application is run.

Override

In rare cases you might have to override an existing binding, which can be done with Override:

injector.Override(new(Something), "").To(MyBetterType{})

Override also returns a binding such as Bind, but removes the original binding.

The second argument sets the annotation if you want to override a named binding.

MultiBindings

MultiBindings provide a way of binding multiple implementations of a type to a type, making the injection a list.

Essentially this means that multiple modules are able to register for a type, and a user of this type can request an injection of a slice []T to get a list of all registered bindings.

injector.BindMulti(new(Something)).To(MyType1{})
injector.BindMulti(new(Something)).To(MyType2{})

struct {
	List []Something `inject:""`  // List is a slice of []Something{MyType1{}, MyType2{}}
}

MultiBindings are used to allow multiple modules to register for a certain type, such as a list of encoders, subscribers, etc.

Please not that MultiBindings are not always a clear pattern, as it might hide certain complexity.

Usually it is easier to request some kind of a registry in your module, and then register explicitly.

Bind maps

Similiar to Multibindings, but with a key instead of a list

MyService struct {
	Ifaces map[string]Iface `inject:""`
}

injector.BindMap(new(Iface), "impl1").To(IfaceImpl{})
injector.BindMap(new(Iface), "impl2").To(IfaceImpl2{})

Binding basic types

Dingo allows binding values to int, string etc., such as with any other type.

This can be used to inject configuration values.

Flamingo makes an annotated binding of every configuration value in the form of:

var Configuration map[string]interface{}

for k, v := range Configuration {
	injector.Bind(v).AnnotatedWith("config:" + k).ToInstance(v)
}

In this case Dingo learns the actual type of v (such as string, bool, int) and provides the annotated injection.

Later this can be used via

struct {
	ConfigParam string `inject:"config:myconfigParam"`
}

Dingo Interception

Dingo allows modules to bind interceptors for interfaces.

Essentially this means that whenever the injection of a certain type is happening, the interceptor is injected instead with the actual injection injected into the interceptor's first field. This mechanism can only work for interface interception.

Multiple interceptors stack upon each other.

Interception should be used with care!

func (m *Module) Configure(injector *dingo.Injector) {
	injector.BindInterceptor(new(template.Engine), TplInterceptor{})
	injector.BindInterceptor(new(template.Function), FunctionInterceptor{})
}

type (
	TplInterceptor struct {
		template.Engine
	}

	FunctionInterceptor struct {
		template.Function
	}
)

func (t *TplInterceptor) Render(context web.Context, name string, data interface{}) io.Reader {
	log.Println("Before Rendering", name)
	start := time.Now()
	r := t.Engine.Render(context, name, data)
	log.Println("After Rendering", time.Since(start))
	return r
}

func (f *FunctionInterceptor) Name() string {
	funcname := f.Function.Name()
	log.Println("Function", funcname, "used")
	return funcname
}

Initializing Dingo

At the topmost level the injector is created and used in the following way:

package main

import "flamingo.me/dingo"

func main() {
	injector, err := dingo.NewInjector()
	if err != nil {
		panic(err)
	}

	// The injector can be initialized by modules:
	injector.InitModules(new(BillingModule))

	// Now that we've got the injector, we can build objects.
	// We get a new instance, and cast it accordingly:
	instance, err := injector.GetInstance(new(BillingService))
	if err != nil {
		panic(err)
	}
    billingService := instance.(BillingService) 
	//...
}

Dingo vs. Wire

Recently https://github.com/google/go-cloud/tree/master/wire popped out in the go ecosystem, which seems to be a great choice, also because it supports compile time dependency injection. However, when Dingo was first introduced wire was not a thing, and wire still lacks features dingo provides.

https://gocover.io/github.com/i-love-flamingo/dingo

ModuleFunc

Dingo has a wrapper for func(*Injector) called ModuleFunc. It is possible to wrap a function with the ModuleFunc to become a Module. This is similar to the http Packages HandlerFunc mechanism and allows to save code and easier set up small projects.

Owner
Flamingo
Flamingo is a frontend framework made in go. It is especially useful for building web based sites and portals in a microservice oriented architecture.
Flamingo
Comments
  • 7 invalid inject

    7 invalid inject

    Added a test case for the issue and started with first approach to detect struct receivers by comparing the instance with an empty instance. It seems not to be possible to find out struct receivers using reflection.

    Current solution is not working for cases with struts that have no fields. See failing test cases...

  • support generics

    support generics

    support 1.17 generics like

    instance, err := injector.GetInstance(new(BillingService))
    	if err != nil {
    		panic(err)
    	}
        billingService := instance.(BillingService) 
    

    do not billingService := instance.(BillingService)

  • chore(deps): update module go to 1.19

    chore(deps): update module go to 1.19

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | go (source) | golang | minor | 1.15 -> 1.19 |


    Release Notes

    golang/go

    v1.19.1

    v1.19.0

    v1.18.5

    v1.18.4

    v1.18.3

    v1.18.2

    v1.18.1

    v1.18.0

    v1.17.13

    v1.17.12

    v1.17.11

    v1.17.10

    v1.17.9

    v1.17.8

    v1.17.7

    v1.17.6

    v1.17.5

    v1.17.4

    v1.17.3

    v1.17.2

    v1.17.1

    v1.17.0

    v1.16.15

    v1.16.14

    v1.16.13

    v1.16.12

    v1.16.11

    v1.16.10

    v1.16.9

    v1.16.8

    v1.16.7

    v1.16.6

    v1.16.5

    v1.16.4

    v1.16.3

    v1.16.2

    v1.16.1

    v1.16.0


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by Mend Renovate. View repository job log here.

  • map field injection error without inject tag

    map field injection error without inject tag

    It seems that when we use MultiBinding, the inject tag must be provided on fields. Is this a bug?

    type MapAllInject struct {
    	Readers map[string]io.Reader `inject:""`
    	DefaultReaders map[string]io.Reader
    }
    
    func TestInjectAllMapStruct(t *testing.T) {
    	injector, err := dingo.NewInjector()
    	require.NoError(t, err)
    	require.NotNil(t, injector)
    	injector.BindMap((*io.Reader)(nil), "default").ToInstance(strings.NewReader("default"))
    	injector.BindMap((*io.Reader)(nil), "hello").ToInstance(strings.NewReader("hello"))
    
    	ret, err := injector.GetInstance((*MapAllInject)(nil))
    	require.NoError(t, err)
    	require.NotNil(t, ret)
    
    	retI := ret.(*MapAllInject)
    	require.Equal(t, 2, len(retI.Readers))
    	require.Equal(t, 0, len(retI.DefaultReaders))
    }
    
  • Inject function is called multiple time on singletons w/ provider

    Inject function is called multiple time on singletons w/ provider

    injector.Bind(new(MyStruct)).In(dingo.Singleton)
    injector.Bind(new(Iface1)).ToProvider(func(s *MyStruct) Iface1 { return s })
    injector.Bind(new(Iface2)).ToProvider(func(s *MyStruct) Iface2 { return s })
    

    The Inject function of MyStruct is called for each requested injection of Iface1 or Iface2 The expected behaviour is to call Inject only once for a singleton.

  • chore(deps): update module go to 1.19 - autoclosed

    chore(deps): update module go to 1.19 - autoclosed

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | go (source) | golang | minor | 1.18 -> 1.19 |


    Release Notes

    golang/go

    v1.19.4

    v1.19.3

    v1.19.2

    v1.19.1

    v1.19.0


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

  • chore(deps): update module github.com/stretchr/testify to v1.8.1

    chore(deps): update module github.com/stretchr/testify to v1.8.1

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | github.com/stretchr/testify | require | patch | v1.8.0 -> v1.8.1 |


    Release Notes

    stretchr/testify

    v1.8.1

    Compare Source


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by Mend Renovate. View repository job log here.

  • chore(deps): update irongut/codecoveragesummary action to v1.3.0

    chore(deps): update irongut/codecoveragesummary action to v1.3.0

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | irongut/CodeCoverageSummary | action | minor | v1.2.0 -> v1.3.0 |


    Release Notes

    irongut/CodeCoverageSummary

    v1.3.0

    Compare Source

    v1.3.0 Release Notes

    • Supports glob pattern matching for multiple coverage files (#​35)
    • Improved compatibility with simplecov & simplecov-cobertura (#​37)
    • Now compatible with MATLAB's code coverage plugin (#​53)
    • Docker image signed using Sigstore (#​52)
    • Implemented StepSecurity Secure Workflows (#​50)
    • Compatible with StepSecurity Secure Workflows

    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by Mend Renovate. View repository job log here.

  • chore(deps): update module github.com/stretchr/testify to v1.8.0

    chore(deps): update module github.com/stretchr/testify to v1.8.0

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | github.com/stretchr/testify | require | minor | v1.7.1 -> v1.8.0 |


    Release Notes

    stretchr/testify

    v1.8.0

    Compare Source

    v1.7.5

    Compare Source

    v1.7.4

    Compare Source

    v1.7.3

    Compare Source

    v1.7.2

    Compare Source


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by Mend Renovate. View repository job log here.

  • chore(deps): update actions/setup-go action to v3

    chore(deps): update actions/setup-go action to v3

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | actions/setup-go | action | major | v2 -> v3 |


    Release Notes

    actions/setup-go

    v3

    Compare Source


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

  • chore(deps): update actions/checkout action to v3

    chore(deps): update actions/checkout action to v3

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | actions/checkout | action | major | v2 -> v3 |


    Release Notes

    actions/checkout

    v3

    Compare Source


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

  • Dependency Dashboard

    Dependency Dashboard

    This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

    This repository currently has no open or pending branches.

    Detected dependencies

    github-actions
    .github/workflows/golangci-lint.yml
    • actions/setup-go v3
    • actions/checkout v3
    • golangci/golangci-lint-action v3
    .github/workflows/main.yml
    • actions/checkout v3
    • actions/setup-go v3
    • actions/checkout v3
    • actions/setup-go v3
    • irongut/CodeCoverageSummary v1.3.0
    • marocchino/sticky-pull-request-comment v2
    • actions/checkout v3
    • actions/setup-go v3
    .github/workflows/semanticore.yml
    • actions/checkout v3
    • actions/setup-go v3
    gomod
    go.mod
    • go 1.18
    • github.com/stretchr/testify v1.8.1

    • [ ] Check this box to trigger a request for Renovate to run again on this repository
  • Warn on usage of ChildSingleton inside of singletons

    Warn on usage of ChildSingleton inside of singletons

    If a binding is declared as dingo.ChildSingleton, it has different instances for each area. If a dingo.Singleton gets a dingo.ChildSingleton via injection, it is unclear from which area the instance will come and can lead to unwanted behaviour.

    We should declare this as misusage of the ChildSingleton pattern and at least warn the user.

golang-runtime-di is a framework for runtime dependency injection in go

golang-runtime-di description golang-runtime-di is a framework for runtime dependency injection in go. usage quickstart add it to your go.mod: go get

Aug 1, 2022
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

Oct 16, 2022
πŸ›  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

Dec 31, 2022
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

Jan 1, 2023
Simple Dependency Injection Container
Simple Dependency Injection Container

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

Sep 27, 2022
Simple and yet powerful Dependency Injection for Go
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'

Dec 28, 2022
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

Sep 27, 2022
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

Sep 27, 2022
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

Jun 1, 2022
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

Jan 2, 2023
Generated dependency injection containers in go (golang)
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

Dec 22, 2022
A dependency injection library that is focused on clean API and flexibility

Dependency injection DI is a dependency injection library that is focused on clean API and flexibility. DI has two types of top-level abstractions: Co

Oct 13, 2022
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.

Jan 6, 2023
two scripts written in golang that will help you recognize dependency confusion.
two scripts written in golang that will help you recognize dependency confusion.

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

Mar 3, 2022
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

Dec 25, 2022
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

Jan 3, 2023
Dec 28, 2022
πŸ¦„πŸŒˆ 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.

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

Jan 4, 2023
golang-runtime-di is a framework for runtime dependency injection in go

golang-runtime-di description golang-runtime-di is a framework for runtime dependency injection in go. usage quickstart add it to your go.mod: go get

Aug 1, 2022
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

Oct 31, 2021