SuperAPI AI 工具集

go-dependency-injection

通用与其它

查看项目

更新于 10-15 21:37

技能介绍

本技能介绍 Go 中的依赖注入(DI)实践,核心观点是:DI 在 Go 里是一种模式而非框架,应通过构造函数传参、在 main 中显式装配,只有当手工装配确实带来明显负担时才考虑框架。

用途与主要能力:

  1. 构造函数注入(默认做法):依赖作为显式参数传入,构造函数返回具体类型;服务调用的依赖以接口形式接收。所有依赖都应出现在签名中,若参数过长说明类型职责过多,应拆分而非隐藏依赖。构造函数可校验必需依赖并返回错误,或提供 nil 安全默认值(如 logger = slog.Default())。
  2. 组合根:所有装配集中在一处(main 或其调用的 run 函数),构造顺序即依赖顺序,由编译器检查。任何包都不自行构建依赖,而是接收依赖;不使用 init() 装配,不使用包级 var DB *sql.DB。需要不同装配的两个二进制文件就是两个 main,共用同一批组件。
  3. 消除全局状态:把包级单例改为结构体字段持有依赖。遗留代码迁移路径为:引入结构体,保留已弃用的包级包装函数委托给 main 中构建的实例,逐步迁移调用方后删除包装。可接受的包级状态包括纯常量、已编译正则、由 sync.Once 保护且不持有配置的进程单例。
  4. 小接口用函数依赖:单个函数场景无需完整接口,可直接注入函数,如 now、genID、publish,便于测试替换。
  5. 框架取舍:手工装配的可扩展性超出预期,百行 run 函数仍可读且受编译器检查;当装配跨越数百组件或多团队共用一个二进制时才考虑工具。google/wire 为编译期代码生成,装配仍是普通 Go 且编译期检查,但增加代码生成步骤;uber-go/fx 为运行时容器加生命周期管理,错误在运行时暴露;uber-go/dig 是 fx 的核心运行时容器,无生命周期层。决策规则:优先手工装配;必须生成时优先 wire(编译期失败优于启动期失败);只有同时需要生命周期管理且团队接受运行时容器时才用 fx。不要混用模型:一个组合根只用一种机制。
  6. wire 示例:在 wireinject 构建标签下用 wire.Build 列出构造函数,生成的有序调用文件应提交并像手写代码一样审查。

验证清单:每个服务/处理器通过构造函数参数接收依赖;无包级可变单例;装配集中在 main/run;依赖以接口或函数接收、返回具体类型;构造函数校验必需依赖;组件可通过传入假实现测试;若使用 DI 工具则仅一个且只在组合根;go build ./... 通过,装配错误在编译期暴露。

限制:资料未提供具体版本、安装命令、性能数据或收费信息。