Container 是一款为 Go 语言开发的运行时依赖注入库。Go 语言的语言特性决定了实现一款类型安全的依赖注入容器并不太容易,因此 Container 大量使用了 Go 的反射机制。如果你的使用场景对性能要求并不是那个苛刻,那 Container 非常适合你。
并不是说对性能要求苛刻的环境中就不能使用了,你可以把 Container 作为一个对象依赖管理工具,在你的业务初始化时获取依赖的对象。
使用方式
go get github.com/mylxsw/container
要创建一个 Container 实例,使用 containier.New
方法
cc := container.New()
此时就创建了一个空的容器。
你也可以使用container.NewWithContext(ctx)
来创建容器,创建之后,可以自动的把已经存在的context.Context
对象添加到容器中,由容器托管。
对象绑定
在使用之前,我们需要先将我们要托管的对象告诉容器。Container 支持三种类型的对象管理
- 单例对象
Singleton
- 原型对象(多例对象)
Prototype
- 字符串值对象绑定
Value
所有的对象绑定方法都会返回一个error
返回值来说明是否绑定成功,应用在使用时一定要主动去检查这个error
。确定对象一定会绑定成功(一般不违反文档中描述的参数签名方式,都是一定会成功的)或者要求对象必须要绑定成功(通常我们都要求这样,不然怎么进行依赖管理呢),则可以使用
Must
系列方法,比如Singleton
方法对应的时MustSingleton
,当创建出错时,该方法会直接panic
。
绑定对象时,Singleton
,Prototype
,BindValue
方法对于同一类型,只能绑定一次,如果多次绑定同一类型对象的创建函数,会返回 ErrRepeatedBind
错误。
有时候,希望对象创建函数可以多次重新绑定,这样就可以个应用更多的扩展性,可以随时替换掉对象的创建方法,比如测试时 Mock
对象的注入。这时候我们可以使用 Override
系列方法:
SingletonOverride
PrototypeOverride
BindValueOverride
使用 Override
系列方法时,必须保证第一次绑定时使用的是 Override
系列方法,否则无法重新绑定。
也就是说,可以这样绑定SingletonOverride
->SingletonOverride
,SingletonOverride
->Singleton
,但是一旦出现Singleton
,后续就无法对该对象重新绑定了。
单例对象
使用 Singleton
系列的方法来将单例对象托管给容器,单例对象只会在第一次使用时自动完成创建,之后所有对该对象的访问都会自动将已经创建好的对象注入进来。
常用的方法是 Singleton(initialize interface{}) error
方法,该方法会按照你提供的 initialize
函数或者对象来完成单例对象的注册。
参数 initialize
支持以下几种形式:
-
对象创建函数
func(deps...) 对象返回值
比如
cc.Singleton(func() UserRepo {