uber的fx依赖注入框架:
fx能干啥? 下面睁大氪金x眼:
没有依赖注入框架时写代码:
直白一点的例子:func1()依赖A模块(假设是DB模块),A依赖B模块(假设是网络模块),B依赖C模块(假设是日志模块),如果没有注入框架的话,程序员需要用代码去确保:
先启动C模块,再启动B模块,再启动A模块,再启动func1。 如果函数组件 和 依赖的模块数量比较庞大的话,就很恶心人了。每次修改一点点与模块相关的代码,你都可能不得不再用大量的时间去调整启动顺序。 贼恶心!!!!!!
因此依赖注入的引入可以减少维护依赖关系的精力,专心使开发人员投入到业务开发中来。
有依赖注入框架时写代码:
Golang没有Java那种生态很全的框架,导致Golang中的init被滥用。但是Golang社区有很多提供依赖注入(DI)的框架,比如:
"github.com/facebookgo/inject"
"go.uber.org/fx"
"go.uber.org/dig"
fx用法示例:
app := fx.New(
// 一系列构造函数
fx.Provide(
NewMyConstruct,
NewHandler,
NewMux,
NewLogger,
),
// 构造函数执行完后,执行初始化函数
fx.Invoke(invokeNothingUse, invokeRegister, invokeAnotherFunc, invokeUseMyconstruct, invokeNothingUse),
)
// 这里会依次调用fx.Invoke()注册的函数, fx在调用组件入口时,发现过需要参数,就去fx.Provide()注册的构造函数去创建
// 函数有顺序,有手柄,有参数实体,函数就可以启动起来。
// 带来的好处是:有的组件可能需要很多不同的构造函数,fx自动取按照顺序创建并初始化。 不需要人为去调整,这样节省了程序员的时间。
if err := app.Start(startCtx); err != nil {
log.Fatal(err)
}
Lotus引入fx依赖注入框架,解决的问题:讲各个子模块例如rpc、db、http、libp2p、各种配置参数、随机数、等几百个组件的构造函数用fx.Provide()注册一下先(写入一个容器中,里面有一个map[key]:key是构造函数返回对象的reflect.Type反射类型,val是构造函数(New_XXX_type()) )。
然后通过fx.Invoke()接口,注册各个组件的入口函数。
我总结fx依赖注入框架干的事情主要有3件:
-
提前声明好函数列表里面的函数在调用时,所传入的参数的来源,临时创建:A参数用funcA()创建,B参数用funcB()创建
-
按照顺序,声明需要调用的函数列表
扫描二维码关注公众号,回复: 13306148 查看本文章 -
在app := fx.New() app.Start(ctx)时,依次执行函数列表,遇到需要参数的函数时,就自动推导依赖关系(遍历查表),然后创建参数,然后去执行