U
Uber Fx 依赖注入开发
作者:鹿Sir开发工具v1
使用 Uber Fx 依赖注入框架构建、重构或审查 Go 应用。确保 Fx 的惯用用法:生命周期管理、基于模块的架构、样板代码精简。当用户需要 Go 依赖注入、Fx 框架开发、Fx 模块设计、应用生命周期管理、消除全局状态时触发。触发词:Go、Fx、依赖注入、Uber Fx、生命周期、fx.Provide、fx.Module。
下载量
383
点赞
92
价格
免费
技能文档
---
name: metalagman-go-fx
description: 使用 Uber Fx 依赖注入框架构建、重构或审查 Go 应用。确保 Fx 的惯用用法:生命周期管理、基于模块的架构、样板代码精简。当用户需要 Go 依赖注入、Fx 框架开发、Fx 模块设计、应用生命周期管理、消除全局状态时触发。触发词:Go、Fx、依赖注入、Uber Fx、生命周期、fx.Provide、fx.Module。
title: Uber Fx 依赖注入开发
category: 开发工具
---
# Uber Fx 依赖注入开发
帮助用户用 Uber Fx 构建 Go 应用:消除全局变量、精简样板代码、通过可靠的依赖注入容器管理应用生命周期。
## 技能工作流
### 步骤1:设计模块结构
用 `fx.Module` 组织相关组件(provider、invoke、decorator)为自包含的命名模块:
```go
var Module = fx.Module("server",
fx.Provide(
NewHandler,
NewMux,
),
fx.Invoke(RegisterRoutes),
)
```
命名约定:
- 独立发布的 Fx 模块带 `fx` 后缀(如 `package redisv8fx`)
- 应用内部的一次性模块可省略后缀
最佳实践:
1. **保持精简**:模块只做装配,业务逻辑留在普通 Go 包中
2. **不要转手导出**:避免提供不属于你的类型;提供自己的模块,让用户自行引入依赖方的模块
3. **私有 Provider**:用 `fx.Private` 限制构造产物只在模块内可见,适合内部辅助组件:
```go
fx.Module("auth",
fx.Provide(fx.Private, NewInternalTokenVerifier),
fx.Provide(NewAuthService), // AuthService 能看到 Verifier,其他模块看不到。
)
```
4. **导出边界函数**:`fx.Provide` 用到的构造函数应导出,让用户不借助 Fx 也能使用你的代码(如简单脚本或单元测试)
详细规则见 [references/modules.md](references/modules.md)。
### 步骤2:注册依赖与生命周期
核心规则:
- **消除全局状态**:让 Fx 管理单例并在需要处提供
- **用 `fx.Provide` 注册构造函数**:把应进入容器的组件注册进来
- **`fx.Invoke` 惜用**:只用于必须启动时执行的函数(如启动 HTTP 服务器),大部分逻辑由依赖需求驱动
生命周期钩子用 `fx.Lifecycle`(容器中自动可用)调度:
- `OnStart`:启动后台任务、建立连接、启动服务器;只阻塞调度所需的时间,长任务放入 goroutine;Fx 有启动超时(默认 15s)
- `OnStop`:优雅关停、关闭连接、停止 worker;按**追加的逆序**执行;关停超时默认 15s
```go
func NewServer(lc fx.Lifecycle, logger *zap.Logger) *http.Server {
srv := &http.Server{Addr: ":8080"}
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
go srv.ListenAndServe()
return nil
},
OnStop: func(ctx context.Context) error {
return srv.Shutdown(ctx)
},
})
return srv
}
```
始终成对出现 `OnStart` 与 `OnStop`,确保资源被清理。`OnStart` 按追加顺序执行,`OnStop` 按逆序执行。
详细规则见 [references/lifecycle.md](references/lifecycle.md)。
### 步骤3:组织参数与结果对象
- **`fx.In` 承载依赖**:多个依赖包进内嵌 `fx.In` 的「参数对象」struct,保持构造函数签名整洁并支持向后兼容地追加字段
- **`fx.Out` 承载多个结果**:构造函数的多个输出包进内嵌 `fx.Out` 的「结果对象」struct
- **可选依赖**:`fx.In` 字段加 `optional:"true"` 标签
详细规则见 [references/dependency-objects.md](references/dependency-objects.md)。
### 步骤4:使用注解与值组
- **`fx.Annotate` 保持业务代码干净**:应用标签、转型为接口(`fx.As`)、处理值组,避免业务逻辑被 Fx 类型污染
- **值组收集集合**:用 `group:"name"` 标签把同一接口的多个实现(如多个 HTTP handler)收集到一个 slice
详细规则见 [references/annotations-and-groups.md](references/annotations-and-groups.md)。
### 步骤5:验证与调试
- **图可视化**:用 `fx.DotGraph` 导出依赖图辅助调试
- **启动日志**:检查 Fx 启动日志,确认 provider、invoke、hook 的执行顺序
- **测试**:单元测试用 `fxtest.App` 替代 `fx.App`,确保生命周期钩子被执行且便于捕获错误使用说明
# Uber Fx 依赖注入开发
使用 Uber Fx 依赖注入框架构建、重构或审查 Go 应用。
## 能做什么
- 设计自包含的 Fx 模块结构,消除全局状态与样板代码
- 规范生命周期钩子(OnStart/OnStop)与优雅关停
- 用参数/结果对象、注解、值组保持构造签名稳定
- 指导 `fxtest` 测试与依赖图调试
## 何时使用
- Go 项目引入 Fx 做依赖注入时
- 重构含大量全局单例的 Go 应用时
- Fx 模块设计、生命周期管理、依赖图排查时
## 快速上手
```go
var Module = fx.Module("server",
fx.Provide(NewHandler, NewMux),
fx.Invoke(RegisterRoutes),
)
```
核心原则:模块只做装配、`fx.Invoke` 惜用、`OnStart` 与 `OnStop` 成对出现。完整工作流见 SKILL.md。支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手