Go-Inject 是一个基于 Facebook 的 inject 项目增强的 Go 语言依赖注入框架。它提供了基于反射的依赖注入功能,并在原有基础上增加了深度注入等重要特性。
- ✅ 基于反射的依赖注入:自动解析和注入依赖关系
- ✅ 结构体标签支持:使用 inject:""标签标记需要注入的字段
- ✅ 命名注入:支持通过名称注入特定实例
- ✅ 私有注入:支持创建私有实例
- ✅ 接口注入:自动匹配实现了接口的类型
- ✅ 内联结构体:支持内联结构体的依赖注入
- ✅ 循环依赖检测:自动检测并报告循环依赖
- ✅ 日志支持:可配置的注入过程日志记录
- 🎯 深度注入(Deep Injection):自动注入手动创建对象的内部依赖
- 🔄 递归依赖解析:支持多层嵌套的依赖关系自动解析
- 🛡️ 增强的错误处理:更详细的错误信息和调试支持
- 📊 完善的测试覆盖:包含深度注入的完整测试用例
go get github.com/ComingCL/go-inject深度注入是本项目相对于原始 Facebook inject 的主要增强功能。它解决了以下场景:
场景描述:当你手动创建了一个对象,该对象内部包含其他需要依赖注入的字段时,传统的依赖注入框架无法处理这种情况。
// 传统方式:无法自动注入 d.A 内部的依赖
d := &Service{
    A: &ComponentA{}, // 手动创建的对象,内部的 C 字段无法被自动注入
}深度注入解决方案:自动检测并注入手动创建对象的内部依赖。
- 自动发现:框架检测到字段中存在手动创建的对象
- 自动注册:将发现的对象自动注册到依赖图中
- 递归注入:递归地为该对象的所有依赖字段进行注入
- 多层支持:支持任意深度的嵌套依赖关系
package main
import (
    "fmt"
    "github.com/ComingCL/go-inject"
)
// 定义服务接口
type Logger interface {
    Log(message string)
}
// 实现日志服务
type ConsoleLogger struct{}
func (c *ConsoleLogger) Log(message string) {
    fmt.Println("LOG:", message)
}
// 定义数据库服务
type Database struct {
    Logger Logger `inject:""`
}
func (d *Database) Query(sql string) {
    d.Logger.Log("Executing: " + sql)
}
// 定义用户服务
type UserService struct {
    DB     *Database `inject:""`
    Logger Logger    `inject:""`
}
func (u *UserService) GetUser(id int) {
    u.Logger.Log(fmt.Sprintf("Getting user %d", id))
    u.DB.Query("SELECT * FROM users WHERE id = ?")
}
func main() {
    var g inject.Graph
    
    // 注册依赖
    logger := &ConsoleLogger{}
    db := &Database{}
    userService := &UserService{}
    
    g.Provide(&inject.Object{Value: logger})
    g.Provide(&inject.Object{Value: db})
    g.Provide(&inject.Object{Value: userService})
    
    // 执行依赖注入
    if err := g.Populate(); err != nil {
        panic(err)
    }
    
    // 使用服务
    userService.GetUser(123)
}package main
import (
    "fmt"
    "github.com/ComingCL/go-inject"
)
type ComponentA struct {
    C *ComponentC `inject:""`
}
type ComponentB struct{}
type ComponentC struct {
    B *ComponentB `inject:""`
}
type Service struct {
    A *ComponentA `inject:""`
}
func main() {
    var g inject.Graph
    
    // 注册基础依赖
    b := &ComponentB{}
    c := &ComponentC{}
    
    // 创建包含手动实例的服务
    service := &Service{
        A: &ComponentA{}, // 手动创建的实例
    }
    
    g.Provide(&inject.Object{Value: b})
    g.Provide(&inject.Object{Value: c})
    g.Provide(&inject.Object{Value: service})
    
    // 执行依赖注入(包括深度注入)
    if err := g.Populate(); err != nil {
        panic(err)
    }
    
    // 验证深度注入结果
    fmt.Printf("service.A.C != nil: %v\n", service.A.C != nil)         // true
    fmt.Printf("service.A.C.B != nil: %v\n", service.A.C.B != nil)     // true
    fmt.Printf("service.A.C.B == b: %v\n", service.A.C.B == b)         // true
}type Config struct {
    DatabaseURL string
    RedisURL    string
}
type Service struct {
    MainDB  *Database `inject:"main_db"`
    CacheDB *Database `inject:"cache_db"`
}
func main() {
    var g inject.Graph
    
    mainDB := &Database{URL: "postgres://main"}
    cacheDB := &Database{URL: "redis://cache"}
    service := &Service{}
    
    g.Provide(&inject.Object{Value: mainDB, Name: "main_db"})
    g.Provide(&inject.Object{Value: cacheDB, Name: "cache_db"})
    g.Provide(&inject.Object{Value: service})
    
    g.Populate()
}type Service struct {
    Logger Logger `inject:"private"`  // 创建私有实例
}go-inject/
├── README.md              # 项目文档
├── LICENSE               # MIT 许可证
├── go.mod               # Go 模块文件
├── inject.go            # 核心注入逻辑
├── inject_test.go       # 测试用例
├── structtag.go         # 结构体标签解析
├── structtag_test.go    # 标签解析测试
├── ioc_container.go     # IoC 容器实现
└── examples/            # 使用示例
    ├── basic/           # 基础用法示例
    ├── deep-injection/  # 深度注入示例
    ├── web-service/     # Web 服务示例
    └── advanced/        # 高级用法示例
运行所有测试:
go test -v运行特定测试:
go test -run TestForDeepInject -v查看测试覆盖率:
go test -cover| 特性 | Facebook inject | Go-Inject | 
|---|---|---|
| 基础注入 | ✅ | ✅ | 
| 深度注入 | ❌ | ✅ | 
| 递归依赖 | 部分支持 | ✅ 完全支持 | 
| 错误处理 | 基础 | 增强 | 
| 测试覆盖 | 基础 | 完整 | 
如果你正在使用 Facebook 的 inject 包,迁移到 go-inject 非常简单:
- 更新导入路径:
// 旧的
import "github.com/facebookgo/inject"
// 新的
import "github.com/ComingCL/go-inject"- 
代码无需修改,所有原有功能保持兼容 
- 
可选:利用新的深度注入特性优化你的代码 
我们欢迎社区贡献!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支 (git checkout -b feature/amazing-feature)
- 提交更改 (git commit -m 'Add some amazing feature')
- 推送到分支 (git push origin feature/amazing-feature)
- 开启 Pull Request
# 克隆仓库
git clone https://github.com/ComingCL/go-inject.git
cd go-inject
# 运行测试
go test -v
# 检查代码格式
go fmt ./...
# 运行静态分析
go vet ./...本项目基于 MIT 许可证开源。详见 LICENSE 文件。
- 感谢 Facebook 团队开源的原始 inject 项目
- 感谢所有为本项目做出贡献的开发者
如果你遇到问题或有建议,请:
Go-Inject - 让依赖注入更简单、更强大! 🚀