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?
-
3Automagically 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.Peter– Peter2022-09-03 14:55:23 +00:00Commented Sep 3, 2022 at 14:55
4 Answers
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().
- 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)
}
- 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]
}
- 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/
Comments
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
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
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.