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 - 让依赖注入更简单、更强大! 🚀