安全与风控
在 Go 项目中使用 google/wire…
当代码库导入 github.com/google/wire 或需要在编译期通过 wire.Build 组装应用依赖图时,用代码生成方式构建依赖并让编译器提前发现缺失依赖。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Go 项目中使用 google/wi通用
解决思路
- 安装 wire:`go install github.com/google/wire/cmd/wire@latest`,并在项目中 `go get -tool github.com/google/wire/cmd/wire@latest` 与 `go get github.com/google/wire`。
- 把任意 Go 函数作为 provider:输入是依赖,输出是提供的类型;支持三种返回形式 `T`、`(T, error)`、`(T, func(), error)`,cleanup 函数会被 wire 按逆序串联。
- 用 `wire.NewSet` 把 provider 分组以便复用,set 之间可以互相引用;保持 set 小而稳定,默认每个 package 一个 set。
- 在 injector 文件顶部加 `//go:build wireinject` 构建标签,声明初始化函数,函数体内调用 `wire.Build(...)` 并返回零值占位(或用 `panic(wire.Build(...))` 替代占位返回)。
- 用 `wire.Bind(new(Interface), new(*Concrete))` 显式声明接口绑定,wire 不允许隐式接口满足,避免新增实现类型时依赖图被破坏。
- 用 `wire.Struct(new(Server), "Logger", "DB")` 按字段名注入,或用 `wire.Struct(new(Server), "*")` 注入所有非排除字段,字段可用 `wire:"-"` 标签排除。
- 用 `wire.Value(Foo{X: 42})` 提供常量表达式(不能含函数调用或 channel),用 `wire.InterfaceValue(new(io.Reader), os.Stdin)` 提供接口类型字面量。
- 用 `wire.FieldsOf(new(Config), "DSN", "Addr")` 把结构体字段提升为依赖图中的节点。
- 当同一底层类型需要多个实例时,用命名类型区分(如 `type PrimaryDSN string`、`type ReplicaDSN string`),因为 wire 禁止同一类型有两个 provider。
- 运行 `wire ./...` 重新生成所有 injector;运行 `wire check ./...` 只校验依赖图而不重新生成(适合快速 CI 检查)。
- 在 injector 文件中加 `//go:generate go run github.com/google/wire/cmd/wire`,使 `go generate ./...` 也能触发代码生成。
- 把生成的 `wire_gen.go` 提交到仓库并保持与源码同步,CI 构建依赖它;但绝不手动编辑它,它每次 `wire ./...` 都会被覆盖。
- 每次修改构造函数签名后都要重新运行 `wire ./...`,可将其加入 Makefile 目标或 `go generate`。
- cleanup provider 返回 `(T, func(), error)` 并交给 wire 串联,wire 会生成正确的逆序清理并处理中途构造失败(只运行已构建部分的 cleanup)。
- 调用 cleanup 时先判空:`if cleanup != nil { defer cleanup() }`,因为构造失败时 wire 返回 nil cleanup。
- 保持 injector 文件聚焦:一个文件一个函数,避免一个 `wire.Build` 塞入几十个参数,改为委托给各 package 的 set。
- 单元测试直接手动注入即可,因为 wire 生成的是普通 Go 构造函数,没有容器需要克隆或重置;测试中可用 test injector 把真实 provider 换成 fake。
适用边界 · 注意事项
- 需要生命周期钩子(OnStart/OnStop)、懒加载或运行时动态解析时,应改用 fx/dig/samber/do 等运行时 DI 方案。
- 项目未安装 wire 命令行工具或无法在构建流程中运行代码生成时,不适合采用。
- 依赖图需要频繁在运行时变化或按配置动态决定绑定时,编译期固定图会带来不便。