golang轻量级通用依赖注入容器插件库ore的使用
Golang轻量级通用依赖注入容器插件库Ore的使用
Ore是一个强大且灵活的Go语言依赖注入(DI)库,旨在简化复杂应用程序结构,同时保持性能和模块化。
主要特性
1. 灵活的生命周期管理
- 单例(Singletons): 生命周期贯穿整个应用程序
- 作用域(Scoped): 生命周期绑定到特定上下文
- 瞬时(Transient): 每次解析时创建新实例
2. 别名支持
- 将多个实现链接到同一接口
- 轻松解析首选实现或检索所有注册选项
3. 优雅终止
- 应用程序终止: 按正确依赖顺序关闭所有已解析的单例(实现
Shutdowner
接口) - 上下文终止: 当上下文结束时释放所有已解析的作用域实例(实现
Disposer
接口)
4. 占位符注册
- 在应用程序设置时注册不完整的依赖项
- 在请求或事件发生时动态提供运行时值
5. 多容器(模块)
- 为模块化应用程序创建隔离的依赖关系图
- 通过为每个容器分离服务注册和解析来强制模块边界
安装
go get -u github.com/firasdarwish/ore
快速示例
package main
import (
"context"
"fmt"
"github.com/firasdarwish/ore"
)
// 定义一个服务
type MyService struct {
Message string
}
func main() {
// 注册一个单例服务
ore.RegisterSingleton[SomeServiceInterface](&MyService{Message: "Hello, Ore!"})
// 解析服务
service, _ := ore.Get[*SomeServiceInterface](context.Background())
fmt.Println(service.Message) // 输出: Hello, Ore!
}
完整示例
下面是一个更完整的示例,展示Ore的主要功能:
package main
import (
"context"
"fmt"
"log"
"github.com/firasdarwish/ore"
)
// 定义接口
type Greeter interface {
Greet() string
}
// 实现接口
type EnglishGreeter struct{}
func (g *EnglishGreeter) Greet() string {
return "Hello, World!"
}
type ChineseGreeter struct{}
func (g *ChineseGreeter) Greet() string {
return "你好,世界!"
}
// 需要注入的服务
type App struct {
greeter Greeter `ore:"inject"`
}
func (a *App) Run() {
fmt.Println(a.greeter.Greet())
}
func main() {
// 创建容器
container := ore.NewContainer()
// 注册服务(使用别名)
container.RegisterSingleton[Greeter](&EnglishGreeter{}, ore.WithAlias("en"))
container.RegisterSingleton[Greeter](&ChineseGreeter{}, ore.WithAlias("zh"))
// 注册应用服务
container.RegisterTransient(func(g Greeter) *App {
return &App{greeter: g}
})
// 创建上下文
ctx := context.Background()
// 解析特定语言的greeter
enGreeter, err := container.GetTagged[Greeter](ctx, "en")
if err != nil {
log.Fatal(err)
}
fmt.Println(enGreeter.Greet()) // 输出: Hello, World!
zhGreeter, err := container.GetTagged[Greeter](ctx, "zh")
if err != nil {
log.Fatal(err)
}
fmt.Println(zhGreeter.Greet()) // 输出: 你好,世界!
// 解析App并运行
app, err := container.Get[*App](ctx)
if err != nil {
log.Fatal(err)
}
app.Run() // 默认使用最后注册的Greeter实现
}
生命周期管理示例
package main
import (
"context"
"fmt"
"log"
"github.com/firasdarwish/ore"
)
type Database struct {
conn string
}
func (db *Database) Connect() {
fmt.Println("Connecting to database:", db.conn)
}
func (db *Database) Disconnect() {
fmt.Println("Disconnecting from database:", db.conn)
}
func (db *Database) Dispose() {
db.Disconnect()
}
func main() {
container := ore.NewContainer()
// 注册单例服务
container.RegisterSingleton(func() *Database {
return &Database{conn: "singleton-connection"}
})
// 注册作用域服务
container.RegisterScoped(func() *Database {
return &Database{conn: "scoped-connection"}
})
// 注册瞬时服务
container.RegisterTransient(func() *Database {
return &Database{conn: "transient-connection"}
})
// 创建上下文
ctx := context.Background()
// 解析单例(多次解析返回同一实例)
db1, _ := container.Get[*Database](ctx)
db2, _ := container.Get[*Database](ctx)
fmt.Println("Singleton equal:", db1 == db2) // true
// 创建作用域上下文
scopedCtx, dispose := ore.WithScope(ctx)
defer dispose()
// 解析作用域服务(同一作用域内返回同一实例)
db3, _ := container.Get[*Database](scopedCtx)
db4, _ := container.Get[*Database](scopedCtx)
fmt.Println("Scoped equal:", db3 == db4) // true
// 解析瞬时服务(每次返回新实例)
db5, _ := container.Get[*Database](scopedCtx)
db6, _ := container.Get[*Database](scopedCtx)
fmt.Println("Transient equal:", db5 == db6) // false
}
Ore提供了强大的依赖注入功能,可以帮助您构建更模块化、更易测试的Go应用程序。
更多关于golang轻量级通用依赖注入容器插件库ore的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang轻量级通用依赖注入容器插件库ore的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang轻量级依赖注入容器ore使用指南
ore是一个轻量级的Go语言依赖注入容器库,它提供了简单易用的依赖注入功能,适合中小型项目使用。下面我将详细介绍ore的使用方法。
安装
go get github.com/hex-techs/ore
基本用法
1. 容器初始化
import "github.com/hex-techs/ore"
func main() {
// 创建一个新的容器
c := ore.NewContainer()
// 或者使用单例容器
ore.Singleton(func() *Service {
return &Service{}
})
}
2. 注册服务
ore支持三种注册方式:
// 1. 注册单例
ore.Singleton(func() *Database {
return &Database{URL: "localhost:5432"}
})
// 2. 注册瞬态实例(每次获取都是新实例)
ore.Transient(func() *Logger {
return &Logger{}
})
// 3. 注册实例(直接注册已存在的实例)
db := &Database{URL: "production-db"}
ore.Instance(db)
3. 获取服务
// 通过类型获取
var db *Database
ore.Resolve(&db)
// 通过接口获取
var logger LoggerInterface
ore.Resolve(&logger)
// 使用MustResolve(如果服务未注册会panic)
svc := ore.MustResolve[*Service]()
4. 构造函数注入
type UserService struct {
db *Database
logger *Logger
}
// 使用ore标签标记需要注入的字段
type UserService struct {
db *Database `ore:"inject"`
logger *Logger `ore:"inject"`
}
// 或者使用构造函数
func NewUserService(db *Database, logger *Logger) *UserService {
return &UserService{db: db, logger: logger}
}
// 注册时
ore.Singleton(NewUserService)
高级用法
1. 命名服务
// 注册命名服务
ore.SingletonNamed("mysql", func() *Database {
return &Database{Driver: "mysql"}
})
ore.SingletonNamed("postgres", func() *Database {
return &Database{Driver: "postgres"}
})
// 获取命名服务
var db *Database
ore.ResolveNamed("mysql", &db)
2. 生命周期管理
type Resource struct {
// ...
}
func (r *Resource) Close() error {
// 清理资源
return nil
}
// 注册实现了io.Closer的服务
ore.Singleton(func() *Resource {
return &Resource{}
})
// 容器关闭时会自动调用Close()
defer c.Close()
3. 模块化注册
type DatabaseModule struct{}
func (m *DatabaseModule) Configure(c *ore.Container) {
c.Singleton(func() *Database {
return &Database{URL: "localhost:5432"}
})
}
type LoggerModule struct{}
func (m *LoggerModule) Configure(c *ore.Container) {
c.Singleton(func() *Logger {
return &Logger{Level: "info"}
})
}
// 注册模块
c := ore.NewContainer()
c.Configure(&DatabaseModule{}, &LoggerModule{})
完整示例
package main
import (
"fmt"
"github.com/hex-techs/ore"
)
// 定义服务接口
type Logger interface {
Log(message string)
}
// 实现服务
type ConsoleLogger struct{}
func (l *ConsoleLogger) Log(message string) {
fmt.Println(message)
}
// 数据库服务
type Database struct {
URL string
}
func (d *Database) Query() string {
return "Data from " + d.URL
}
// 用户服务
type UserService struct {
db *Database `ore:"inject"`
logger Logger `ore:"inject"`
}
func (s *UserService) GetUser(id int) {
s.logger.Log(fmt.Sprintf("Getting user %d", id))
data := s.db.Query()
s.logger.Log(fmt.Sprintf("Got data: %s", data))
}
func main() {
// 注册服务
ore.Singleton(func() *Database {
return &Database{URL: "localhost:5432"}
})
ore.Singleton(func() Logger {
return &ConsoleLogger{}
})
ore.Singleton(func(us *UserService) *UserService {
return us
})
// 获取用户服务
userService := ore.MustResolve[*UserService]()
userService.GetUser(1)
// 输出:
// Getting user 1
// Data from localhost:5432
}
注意事项
- ore是线程安全的,可以在并发环境下使用
- 循环依赖会导致panic,需要设计时避免
- 推荐使用接口而不是具体类型注册服务
- 对于大型项目,可以考虑更成熟的DI框架如wire或dig
ore以其简单性和轻量级特性,非常适合中小型Go项目快速实现依赖注入,减少了手动管理依赖的复杂度。