DEV Community

shanjunmei
shanjunmei

Posted on

What should a modern Go dependency injection framework look like?

Go DI has always been a trade-off.

Runtime DI frameworks provide a convenient API, but they rely on reflection and discover dependency problems during application startup.

Compile-time DI frameworks avoid those problems, but some APIs become verbose and less ergonomic.

I have been exploring a different approach:

dig — compile-time dependency injection for Go with an Fx-style API and Wire-style code generation.

Repository:
https://github.com/shanjunmei/dig

The main design goals are:

dependency graph resolution during go generate
zero runtime reflection
zero runtime dependency after code generation
generated code is plain Go
minimal API: Build, Provide, Supply, Invoke, Module

Example:

func InitApp() func(context.Context) error {
    return dig.Build(
        dig.Provide(NewConfig),
        dig.Provide(NewDatabase),
        dig.Invoke(StartServer),
    )
}
Enter fullscreen mode Exit fullscreen mode

After generation, the application does not depend on a DI runtime.

Some design questions I would like feedback on:

Do you prefer compile-time DI or runtime DI in large Go projects?
Is avoiding reflection an important advantage in practice?
Are there DI patterns from Wire/Fx/custom solutions that should be preserved?
What API choices would make a Go DI library feel natural?

The goal is not to create another DI library for its own sake, but to explore what a more Go-like DI design could look like.

Feedback and criticism are welcome.

Top comments (0)