dig(Dependency Injection for Go)是 Uber 开源的一款基于反射的依赖注入工具,专为 Go 语言设计。它通过自动管理对象间的依赖关系,简化代码结构,适用于构建应用框架(如 Uber 的 Fx)或初始化复杂依赖图。 • GitHub 地址: uber-go/dig
• 反射驱动:无需代码生成,通过反射分析函数参数和返回值,自动解析依赖。
• 容器化管理:通过 dig.Container 管理所有依赖的构造函数和实例。
• 启动时依赖解析:适合在应用启动阶段构建依赖图,避免运行时开销。
• 稳定性:遵循 SemVer 规范,v 1 版本无破坏性变更。
• 轻量级:核心代码简洁,适合作为底层工具集成到框架中。
• ✅ 适用场景: • 构建应用框架(如 Fx)。 • 初始化阶段集中管理复杂依赖(如配置、数据库连接、服务层)。 • ❌ 不适用场景: • 替代完整的应用框架(需结合 Fx 等)。 • 运行时动态依赖注入。
package daemon
import (
"fmt"
"go.uber.org/dig"
)
type Config struct {
Addr string
}
func NewConfig() *Config {
return &Config{Addr: ":8080"}
}
type Server struct {
cfg *Config
}
func NewServer(cfg *Config) *Server {
return &Server{cfg: cfg}
}
func ABC() {
c := dig.New()
c.Provide(NewConfig)
c.Provide(NewServer)
c.Invoke(func(s *Server) {
fmt.Println("Server started at", s.cfg.Addr)
})
}
Server started at :8080将多个相同类型的实例注入为切片,适用于插件化场景:
c.Provide(func() *Logger { return NewFileLogger() }, dig.Group("loggers"))
c.Provide(func() *Logger { return NewConsoleLogger() }, dig.Group("loggers"))
// 使用时注入 []*Logger
c.Invoke(func(loggers []*Logger) {
for _, l := range loggers {
l.Log("Hello")
}
})动态增强已有依赖:
c.Decorate(func(l *Logger) *Logger {
return l.WithLevel("debug")
})通过返回接口类型实现接口-具体类型绑定:
type Writer interface { Write([]byte) }
type FileWriter struct{}
func NewWriter() Writer { return &FileWriter{} }
c.Provide(NewWriter) // 依赖注入时识别为 Writer 接口• 性能:反射在启动时一次性解析依赖,对运行时性能无影响,但大型项目可能增加启动时间。
• 错误处理:支持构造函数返回 error,容器会捕获并终止初始化。
• 循环依赖检测:启动时自动检测循环依赖(如 A → B → A)并报错。
工具 | 特点 | 适用场景 |
|---|---|---|
dig | 反射驱动,灵活,启动时解析 | 中小项目、框架集成 |
wire | 代码生成,编译时检查,高性能 | 大型项目、追求性能 |
Fx | 基于 dig 的应用框架,生命周期管理 | 全功能应用开发 |
dig 是 Go 生态中轻量且强大的依赖注入工具,适合需要灵活依赖管理的场景。结合 Fx 可构建完整的应用框架,但需注意反射带来的启动开销。对于性能敏感项目,可考虑代码生成方案(如 wire)。