Skip to main content

fx

tip
  • fx.Supply 不能直接提供 interface
    • Go 类型检测不到, 使用 constructor 返回
  • fx.In 和 fx.Out 要求字段 exported
  • 不支持 lazy - 面向启动时初始化设计,而非请求时配置
使用 IoC 可能导致维护性变差

使用 fx 作为 container 虽然当时使用时构建起来容易,但是一段时间后再理解逻辑需要一定时间。

替代选择:

  • Service Context 对象 - 包含所有的依赖信息,透明
  • 选择 wire - 编译时生成
type HandlerParams struct {
fx.In // consume - 多入参 - 增强可读性

Users *UserGateway
Comments *CommentGateway
Posts *PostGateway
Votes *VoteGateway
AuthZ *AuthZGateway

Cache *redis.Client `optional:"true"` // 可选参数

WriteToConn *sql.DB `name:"rw"` // 命名
ReadFromConn *sql.DB `name:"ro" optional:"true"`

Handlers []Handler `group:"server"` // 多实例 - 不保证顺序
}

type ConnectionResult struct {
fx.Out // provide

ReadWrite *sql.DB `name:"rw"`
ReadOnly *sql.DB `name:"ro"`

Handler Handler `group:"server"`

Handler []int `group:"server"` // Consume as [][]int
Handler []int `group:"server,flatten"` // Consume as []int
}

func NewConnection(p HandlerParams) ConnectionResult {
// ...
}

// 可以直接使用 Annotated 配置名字和分组
fx.Provide(fx.Annotated{
Name: "ro",
Group: "server",
Target: NewReadOnlyConnection,
})