1

I come from node.js and nest.js world, where DI is simple and provided by a framework. Can or should I consider using dependency injection when building services on go?

1
  • 3
    Automagically wiring up services and whatnot isn't idiomatic in Go. Just write normal constructors and call them in main (or an equivalent functions). There probably exist libraries that provide the magic you're looking for, so if you really want it I'm sure you can find some. Recommendations are off-topic on SO, though. Commented Sep 3, 2022 at 14:55

4 Answers 4

3

Yes, it is possible in Go.

A simple three-step DI system for Go:

Imagine you have a package A that shall not import package B but call some functions from that package; for example, functions Load() and Save().

  1. In package A, define an interface type with these functions.
type Storage interface {
    Load(string) []byte
    Save(string, []byte)
}

A type in package A can then refer to that interface and call Load() and Save() without knowing the actual receivers of these calls.

type StructA struct {
    content []byte
    storage Storage
}

func NewStructA(s Storage) *StructA {
    return &StructA{
        content: ...,
        storage: s,
    }
}

func (a *StructA) Save(name string) {
    a.storage.Save(name, a.content)
}

func (a *StructA) Load(name string) {
    a.content = a.storage.Load(name)
}
  1. In package B, implement Load() and Save().
type StoreB struct {
    poem []byte
}

func (b *StoreB) Save(name string, contents []byte) {
    // let's say StoreB contains a map called data
    b.data[name] = contents
}

func (b *StoreB) Load(name string) []byte {
    return b.data[name]
}
  1. In package main, connect the wires.
storage := B.StructB
a := A.NewStructA(storage)
a.Save()

Now you can add other storage provides (package C, D,...) and wire them up in main.

storage2 := C.StructC
a2 := A.NewStructA(storage2)
a2.Save()

A more detailed discussion is here: https://appliedgo.net/di/

Sign up to request clarification or add additional context in comments.

Comments

2

A dependency injection based application framework for Go. https://github.com/uber-go/fx

A reflection based dependency injection toolkit for Go. https://github.com/uber-go/dig

Comments

0

Yes, you should consider DI in go, DI has same advantages in go as any other language. It can be easily achieved in go by using interfaces.

2 Comments

I'm using interfaces, and yeah, this provides me "dependency inversion" of SOLID. What about "auto" dependency injection libraries? Just like in Spring Boot or in Nest.js?
go has reflection and tags, ~ reflection and annotations in spring, so yes there may be some libraries that provide similar DI functionality.
0

Due to support of first class functions in Golang, DI can be implement with functional programming approach. When functions initialized lazy and pass context through each other.

Something like Reader monad, popular way for DI in functional programming world.

If you already come from Node.js/Nest.js world, maybe you can know fp-ts Reader monad

I implemented for Golang Functional programming context library, maybe it can useful for DI with FP style, which mostly inspired from Reader monad.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.