V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
inSpring
V2EX  ›  Go 编程语言

做个调查:你们的 Go 项目中会用到依赖注入吗?比如用到如 wire、dig 之类的库?

  •  2
     
  •   inSpring · 2 天前 · 5490 次点击
    65 条回复    2025-05-13 20:16:30 +08:00
    jollywang
        1
    jollywang  
       2 天前   ❤️ 3
    研究了这几个库, 对代码的结构组织结构影响还挺大的, 和 java 的 spring 完全不是一个概念
    这么说吧, 不如就是一个全局的 Container struct, 里面定义了各种变量, 需要用的地方再引入, 这样对心智负担也较小, 更容易维护
    gowk
        2
    gowk  
       2 天前
    赞同楼上兄弟说的,感觉 Go 根本没必要用这些 DI 库,徒增复杂度
    LitterGopher
        3
    LitterGopher  
       2 天前   ❤️ 1
    我不会主动使用,但是如果有一个对技术和 golang 半懂不懂的领导一定要求你要使用这个东西——即便他连这个 wire 的基础使用连一知半解都算不上——那我也没有办法。

    我不赞同,但是如果你坚持那我就没必要坚持找不快。
    matrix1010
        4
    matrix1010  
       2 天前   ❤️ 1
    建议调查加上: 你们的 Go 项目写单元测试吗?写单元测试却没有使用依赖注入的情况下是如何 mock 各种依赖的
    DonkeyKane
        5
    DonkeyKane  
       2 天前
    小项目不用,大项目不得不用。
    Ayanokouji
        6
    Ayanokouji  
       2 天前
    用依赖注入,但不使用框架。
    从这个项目学的思路 https://github.com/mikestefanello/pagoda
    StarUDream
        7
    StarUDream  
       2 天前
    #4 同意,我自己用依赖注入的时候也发现单元测试没法搞。
    matrix1010
        8
    matrix1010  
       2 天前
    框架以前我都推荐 Grafana ,但 Grafana 太复杂了而且有大量历史遗留代码,很多地方风格也不太统一。有兴趣的可以参考一下我最近的这个项目: https://github.com/Yiling-J/tablepilot. 在 Go 的基础上支持 CLI+WebUI+App, 同时写单元测试
    BeautifulSoap
        9
    BeautifulSoap  
       2 天前 via Android
    对于说 go 用不到 di 的,我很好奇你们平时用的项目都小到各种依赖能手动注入的吗?

    对于大点的项目,注入依赖项肯定需要 di 框架。我主要用 dig
    BeautifulSoap
        10
    BeautifulSoap  
       2 天前 via Android
    @jollywang 全局的 Container struct (说白了就是全局变量存在那的一个 singleton 模式)的话,我就比较好奇,你这存在那的对象是在 init 阶段就 new 好还是等需要的时候再 new (即 lazy init )?后者的话那就必须要考虑线程安全问题。再一个既然是 singleton 了,如果我想要每次调用都生成一个全新的对象的话,是不是还得实现非 singleton 的功能。
    那么这一套实现下来,在我看来不就是实现了半个 di 框架了吗
    NotLongNil
        11
    NotLongNil  
       2 天前
    不用。90% 的项目其实都没必要依赖注入,即使是 java 也一样
    MemoryCorner
        12
    MemoryCorner  
       2 天前
    同好奇,如果不用依赖注入,你们单侧依赖怎么 mock ?
    seth19960929
        13
    seth19960929  
       2 天前
    单元测试和依赖注入没什么关系吧,怎么楼上扯歪了,golang 这么多内置库没用依赖注入也不影响单元测试,一个包内的全局变量,然后包内测试刘 OK 克
    dobelee
        14
    dobelee  
       2 天前
    @MemoryCorner interface+monkey
    AEnjoyable
        15
    AEnjoyable  
       2 天前 via Android
    我主导的一个大项目用到了自己写的 ioc ,通过依赖注入来适应不同的 tenants 。
    单元测试覆盖所有 ioc 托管对象的接口,业务代码写完只需要去测试环境做一下集成测试就行。
    虽然复杂度确实提升了,但后期维护+新增租户啥的都很方便,没啥负担
    CLMan
        16
    CLMan  
       2 天前
    https://yangjunhui.monster/t/1094915 半年经贴,回答者都是些熟面孔,回答也类似。
    lanlanye
        17
    lanlanye  
       2 天前
    你都用 Go 了……那你猜 Google 为什么要写 wire ?
    fgwmlhdkkkw
        18
    fgwmlhdkkkw  
       2 天前
    https://github.com/zzztttkkk/dic

    我自己也弄了一个。
    tairan2006
        19
    tairan2006  
       1 天前
    不会,主要是不好用,徒增复杂度。
    dwu8555
        20
    dwu8555  
       1 天前
    那你为啥不用 java
    fffq
        21
    fffq  
       1 天前
    不用,那可读性真差
    SimbaPeng
        22
    SimbaPeng  
       1 天前
    wire 、fx 都用过
    CoderGeek
        23
    CoderGeek  
       1 天前   ❤️ 1
    我用的 uber 的 fx 感觉不多不少 凑合用
    Jaeger
        24
    Jaeger  
       1 天前
    有用 wire ,感觉还是很好用的,使用依赖注入模式会让代码清晰很多,使用 wire 自动生成注入代码可以节省很多工作量。
    gl3081
        25
    gl3081  
       1 天前
    微服务使用 DI 框架还是非常方便的,可以灵活组合不同的服务:
    参考: https://github.com/moke-game/platform(10+个游戏微服务)
    gl3081
        26
    gl3081  
       1 天前
    sampeng
        27
    sampeng  
       1 天前
    用过一段时间。心智负担比较大。。。时间长了就给忘了。反正都是 ai 写。就其实还好,多一个 request 问罢了,适当的冗余是很方便查问题的。用的东西多了有时候不是什么好事
    NX2023
        28
    NX2023  
       1 天前
    @matrix1010 #4 我之前会弄一个初始化函数替换所有全局变量例如 *gorm.DB ,其他的就直接 gomonkey 了😅
    jollywang
        29
    jollywang  
       1 天前
    @BeautifulSoap 确实, 单测会有些蹩脚, 使用了条件编译来实现
    但这个也是受限与小组内开发水平也是参次不齐的限制, java/go/python 都有涉及, 人均负责几个项目, 偶尔需要顶一下. 加之微服务隔离环境, 单个项目粒度控制的比较小, 倒也没那么重吧
    NX2023
        30
    NX2023  
       1 天前   ❤️ 1
    我是会用的,当然用依赖注入不一定等于使用依赖注入框架

    如果框架我用 https://github.com/samber/do

    个人心理洁癖,感觉不依赖注入就跟私拉电线一样这里调一下那里调一下,看着乱心里不舒服(
    依赖注入之后等于是把电线捆好放在这里,一个模块一个模块分割的很清晰

    当然依赖注入的优点我也是很赞成的,包括容易写测试
    haython
        31
    haython  
       1 天前
    有些人根本搞不明白依赖注入,所以就一刀切,干脆不学也不用
    changz
        32
    changz  
       1 天前 via Android
    wire 加的复杂度在哪里?自己手写和生成区别不大。。。
    koujianshusheng
        33
    koujianshusheng  
       1 天前
    上个项目 kratos 里就集成了 wire
    可以规范代码
    刚开始上手有点难理解觉得
    后面用起来就 ok 了
    latifrons
        34
    latifrons  
       1 天前
    我在大量项目里都用了 https://github.com/golobby/container ,支持注解式注入和懒加载,很好用。

    其实很多人开发 Go 并没有想清楚以下问题,直接短平快,但是大型项目里往往发现代码越写越乱:
    1 ,程序初始化一次性任务、定时任务、长运行服务之间如何安排启动顺序;
    2 ,命令行解析和配置文件层级及优先级关系
    3 ,RPC/GRPC 服务业务报错/系统报错,错误代码处理
    4 ,服务 SIGTERM 优雅退出处理
    5 ,日志等级管理( DB ,rpc ,grpc ,resty )
    6 ,单例管理(如*gorm.DB )

    我也是迭代了很多项目,慢慢把这么多东西都抽离成了一个自用独立框架的
    qq135449773
        35
    qq135449773  
       1 天前
    当然会用。

    对于 DI 这种需求可以说 wire 这种纯静态的方案做的恰到好处。

    跑到 runtime 里到处 reflect 那样就有点得不偿失了。

    本质上都是到处飞 `NewXXXXX` ,为何不用一种方法让这个过程更高效可读一点?
    sotvokun
        36
    sotvokun  
       1 天前
    一开始没准备用,但是写到各个组件之间的依赖太多了,手动初始化再在构造函数或者初始化结构体的时候传入也太麻烦了,干脆就直接用 wire 自动生成了。

    虽然差别不大,但是生成出来的代码也不用在意人能不能读懂,能用就行,手写的话就要加入可读性维护的考虑了
    zengxs
        37
    zengxs  
       1 天前   ❤️ 1
    用 uber/fx 。小项目用不用 DI 无所谓,但是项目比较大的情况下还是有必要用 DI 库的
    HtPM
        38
    HtPM  
       1 天前
    主要还是钱没给够。我未必还要写单元测试?直接手动 request 一把梭哈
    HypoChen
        39
    HypoChen  
       1 天前   ❤️ 1
    有一个阶段喜欢用 DI 框架,大部分是突增烦恼。

    事实上,只需要使用「将 Interface 定义在用的地方,而不是实现的地方」这个小技巧,就基本可以获得 DI 的好处了
    devhxy
        40
    devhxy  
       1 天前
    推荐一个轻量级的:github.com/samber/do
    Visionhope
        41
    Visionhope  
       1 天前   ❤️ 1
    之前用的 wire ,新项目试了下 fx ,感觉要流畅一些。至于使用 DI 框架的好处,那就是定义好初始化函数,剩下的交给框架就行了。个人还是蛮喜欢的。
    testliyu
        42
    testliyu  
       1 天前
    我们项目里没做
    qloog
        43
    qloog  
       1 天前
    用到了,使用 google 的 wire: https://github.com/go-eagle/eagle-layout
    totoro52
        44
    totoro52  
       1 天前
    依赖注入啥时候和 java 绑定并成了一种邪恶的东西呢。。。他明明是一种思想
    zthxxx
        45
    zthxxx  
       1 天前   ❤️ 1
    目前 uber/fx
    james122333
        46
    james122333  
       1 天前 via Android
    这之前已经有讨论过了 我倾向不用
    package 下直接初始化 struct 就可以了
    一楼讲的其实就是把 struct 当命名空间用 很 js 的方式
    go 已经有命名空间了 所以不用这种方式实现一样结果更单纯
    spring 下的与一楼讲的相似 只不过是换成阵列 徒增性能损耗
    这种方式因语言本身 import 功能就已经解决依赖问题
    只要没 import 循环问题即可 其它语言的都可能会有依赖循环问题 这是种对语言特性深度了解并使用本身具备的功能减少过多嵌套的方式个人认为最佳

    至于测试... 可以用 go test
    本身就已经有的功能
    james122333
        47
    james122333  
       1 天前 via Android
    虽然我本身不怎么想写测试
    james122333
        48
    james122333  
       1 天前 via Android
    还有一点 直接用 import 在编译或开发时就会检查依赖了 错了代表设计不合理
    wangritian
        49
    wangritian  
       1 天前
    学习了本贴和一些链接的内容,然后决定继续手搓
    Trim21
        50
    Trim21  
       1 天前   ❤️ 1
    就算用 di 也不该用 dig ,应该用 fx (
    lujiaxing
        51
    lujiaxing  
       23 小时 35 分钟前
    看到这标题我真是一口可乐喷出来了.
    go 的出现本来就是为了规避这些复杂的要死的设计模式.
    大道至简.
    结果你把依赖注入都搬出来了.
    那你为什么不直接用 ASP.NET Core 算了.
    zjsxwc
        52
    zjsxwc  
       23 小时 24 分钟前
    wire 、dig 之流太恶心,不如直接用 init 来依赖注入,当然要注意 init 顺序
    wysnxzm
        53
    wysnxzm  
       21 小时 54 分钟前
    @totoro52 #44 因为某些人给自己打上了思想钢印
    sophos
        54
    sophos  
       21 小时 25 分钟前
    哈哈哈,月经贴鉴定完毕,总结一下 :-)
    - 个人的、不写单测的项目不需要用依赖注入,代码抽象的复杂度会上升
    - 多人参与的、迭代频繁的项目,用依赖注入会让大家都舒服,用类似的模式写代码和测试

    刚好回头刷了下我早前开源的 Go 依赖注入框架,发现多了几个 star……

    https://github.com/go-kod
    1283095131
        55
    1283095131  
       20 小时 1 分钟前   ❤️ 1
    fx 挺好用的
    mengyx
        56
    mengyx  
       19 小时 58 分钟前   ❤️ 1
    以前用过 wire ,现在用 fx 比较多;不用依赖注入的话,业务的单元测试会很难写
    lysShub
        57
    lysShub  
       19 小时 51 分钟前
    @matrix1010 1.设计的时候解耦一下、测试专门搞个 mock 实现; 2. go 有几个 monkey 库可以用
    kkhaike
        58
    kkhaike  
       19 小时 24 分钟前
    说 fx 好用的我都点了赞
    NoobPhper
        59
    NoobPhper  
       18 小时 22 分钟前
    把一件复杂的事情做简单 是件很难得事情看来
    EscYezi
        60
    EscYezi  
       18 小时 18 分钟前 via iPhone
    以前试过依赖注入框架,后来看 flutter 的时候发现了 riverpod 用的 provider 方式,自己写的小项目也改成类似的方式感觉比较顺手,还可以借助一点 go 本身的循环依赖检查
    https://gist.github.com/yeziyezi/97d4e75dc59e5d9d40f3d88889552cb5
    mayli
        61
    mayli  
       16 小时 43 分钟前
    higker
        62
    higker  
       16 小时 12 分钟前
    Go 语言最大优势就是携程并发和大包 native code 这些... PL 设计层面 错误处理 defer 关键资源关闭 和 锁颗粒度冲突 隐式接口 大小写反射问题 最小封装单位是包 而且 struct 是不能有统一的构造函数,只能在包上做构造函数,玩设计模式就残废。

    依赖注入相比动态 VM 语言简直就是残废,通过代码生成来玩,或者一些开发者就不关注这个问题,直接引编码进去,好的项目结构应该是每个组件使用统一构造函数进行依赖注入。没有依赖注入,写单元测试却没有使用依赖注入的情况下是如何 mock 各种依赖的。很多程序员根本搞不明白依赖注入,(其实就是狗屎代码,或者第一门 PL 就是 Go 这种垃圾语言),所以就一刀切干脆不学也不用。

    Go 这种语言依赖注入目前解决方案就是通过静态分析,要么自己把项目结构设计好一点,手动构造函数初始化,不写测试。拿去写一些中间件可以,写业务还不如回去写 js 语言。不要被一些国内一些 sx 布道师吹着多么多么好,误入到这个坑里面,目前云原生基础设施可以去学 Rust ,Java 云原生方案也要很多 Spring Native Qurakus Vert.x graalvm.org AOT 这些...
    james122333
        63
    james122333  
       15 小时 39 分钟前 via Android
    @higker

    go 没有建构子但你可以自己定义函数在注入时候 new 和运行 并返回自己 可搭配界面和范型

    依赖注入个人觉得是非必要功能 因为它做的其实很有限 但非要的话显式注入可追溯更好 可以看看我讲的 含测试

    多数依赖注入其实做的事情就是静态变量在做的事情
    多绕了一圈代码不是很美的 在包内的静态变量还更好管理 因为可以用包来分类 依赖注入的初始化只是种不同写法

    就我用来写业务感受其实没什么分别 活用语言特性否则你用哪种语言都一样 只能一直当框架调包侠 其实框架做的事情也就那样
    Trim21
        64
    Trim21  
       11 小时 47 分钟前 via Android
    @mayli dig 的 readme 里面提到的那个 fx
    server
        65
    server  
       11 小时 40 分钟前
    没有 wire, 真解耦不了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1436 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:56 · PVG 07:56 · LAX 16:56 · JFK 19:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.