Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ComingCL/go-inject

Repository files navigation

Go-Inject - Enhanced Dependency Injection Framework

Go Version License Tests

Go-Inject 是一个基于 Facebook 的 inject 项目增强的 Go 语言依赖注入框架。它提供了基于反射的依赖注入功能,并在原有基础上增加了深度注入等重要特性。

🚀 主要特性

原有特性(继承自 Facebook inject)

  • 基于反射的依赖注入:自动解析和注入依赖关系
  • 结构体标签支持:使用 inject:"" 标签标记需要注入的字段
  • 命名注入:支持通过名称注入特定实例
  • 私有注入:支持创建私有实例
  • 接口注入:自动匹配实现了接口的类型
  • 内联结构体:支持内联结构体的依赖注入
  • 循环依赖检测:自动检测并报告循环依赖
  • 日志支持:可配置的注入过程日志记录

🆕 增强特性

  • 🎯 深度注入(Deep Injection):自动注入手动创建对象的内部依赖
  • 🔄 递归依赖解析:支持多层嵌套的依赖关系自动解析
  • 🛡️ 增强的错误处理:更详细的错误信息和调试支持
  • 📊 完善的测试覆盖:包含深度注入的完整测试用例

📦 安装

go get github.com/ComingCL/go-inject

🎯 深度注入特性详解

什么是深度注入?

深度注入是本项目相对于原始 Facebook inject 的主要增强功能。它解决了以下场景:

场景描述:当你手动创建了一个对象,该对象内部包含其他需要依赖注入的字段时,传统的依赖注入框架无法处理这种情况。

// 传统方式:无法自动注入 d.A 内部的依赖
d := &Service{
 A: &ComponentA{}, // 手动创建的对象,内部的 C 字段无法被自动注入
}

深度注入解决方案:自动检测并注入手动创建对象的内部依赖。

深度注入工作原理

  1. 自动发现:框架检测到字段中存在手动创建的对象
  2. 自动注册:将发现的对象自动注册到依赖图中
  3. 递归注入:递归地为该对象的所有依赖字段进行注入
  4. 多层支持:支持任意深度的嵌套依赖关系

📚 使用指南

基本用法

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 迁移

如果你正在使用 Facebook 的 inject 包,迁移到 go-inject 非常简单:

  1. 更新导入路径:
// 旧的
import "github.com/facebookgo/inject"
// 新的
import "github.com/ComingCL/go-inject"
  1. 代码无需修改,所有原有功能保持兼容

  2. 可选:利用新的深度注入特性优化你的代码

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/amazing-feature)
  3. 提交更改 (git commit -m 'Add some amazing feature')
  4. 推送到分支 (git push origin feature/amazing-feature)
  5. 开启 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 项目
  • 感谢所有为本项目做出贡献的开发者

📞 支持

如果你遇到问题或有建议,请:

  1. 查看 examples 目录中的示例
  2. 搜索现有的 Issues
  3. 创建新的 Issue 描述你的问题

🔗 相关链接


Go-Inject - 让依赖注入更简单、更强大! 🚀

About

Go-Inject 是一个基于 Facebook 的 [inject](https://github.com/facebookarchive/inject) 项目增强的 Go 语言依赖注入框架

Topics

Resources

License

Stars

Watchers

Forks

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /