通过对web应用框架背后原理的探索,引入了依赖注入的概念。如果你需要读懂或者写一个框架的话,依赖注入的思想绝对能帮到你。本文记录对依赖注入的探索。
区分依赖和宿主
现在我们把问题简化一下:
package main
import "fmt"
func MethodA(name string, f func(a int, b string)) {
fmt.Println("Enter MethodA:", name)
f(3030, "zdd") // 给f注入参数
fmt.Println("Exit MethodA:", name)
}
func MethodB(a int, b string) {
fmt.Println(a, b)
}
func main() {
d := MethodB
MethodA("zddhub", d)
}
在上述的例子中,为了完成MethodA的功能,需要依赖MethodB方法的实现,把MethodB方法叫做MethodA的依赖(Dependency), MethodA叫做宿主(Host)。上面的例子直接在Host中调用f(3030, "zdd")来给依赖注入参数。或者换一个角度理解,将自定义的方法MethodB整体注入到MethodA的执行环境中。为了通用性考虑,通常会实现一个依赖注入器。
依赖注入器
接下来实现一个依赖注入器(Injector)。在web应用框架的例子中,我们发现,在Host中,只能拿到依赖方法的参数类型,而我们需要将参数类型和参数值建立联系,因此,在Injector中封装一个map[Type]Value是自然而然的选择。
package main
import (
"fmt"
"reflect"
)
type Injector struct {
mappers map[reflect.Type]reflect.Value // 根据类型map实际的值
}
func (inj *Injector) SetMap(value interface{}) {
inj.mappers[reflect.TypeOf(value)] = reflect.ValueOf(value)
}
func (inj *Injector) Get(t reflect.Type) reflect.Value {
return inj.mappers[t]
}
func (inj *Injector) Invoke(i interface{}) []reflect.Value {
t := reflect.TypeOf(i)
if t.Kind() != reflect.Func {
panic("Should invoke a function!")
}
inValues := make([]reflect.Value, t.NumIn())
for k := 0; k < t.NumIn(); k++ {
inValues[k] = inj.Get(t.
Go语言中的依赖注入实践与理解

这篇博客探讨了Go语言中的依赖注入概念,通过区分依赖和宿主,介绍了依赖注入器的实现,并讨论了其在测试框架中的应用场景。文章通过示例揭示了依赖注入器的潜在问题及解决方案,鼓励读者深入理解依赖注入以助于框架开发。
最低0.47元/天 解锁文章
744

被折叠的 条评论
为什么被折叠?



