golang 之 wire 库的使用总结

文章目录

    • [1. 写在最前面](#1. 写在最前面)
    • [2. 介绍](#2. 介绍)
      • [2.1 特点介绍](#2.1 特点介绍)
      • [2.2 使用函数解释](#2.2 使用函数解释)
    • [3. 代码示例](#3. 代码示例)
    • [4. 碎碎念](#4. 碎碎念)
    • [5. 参考资料](#5. 参考资料)

1. 写在最前面

之前 review 其他人的代码的时候,看到了关于 wire 库的使用。但当时主要是分析逻辑上的问题,没怎么太学习 wire 库的用法,刚好最近趁着提测的间隙,学习一下!

注:wire 库 github.com/google/wire/cmd/wire 是 Google 开发的一个用于依赖注入的 Go 语言库。Wire 采用了编译时依赖注入的方式,旨在减少运行时开销,提高应用程序的性能和可维护性。

2. 介绍

2.1 特点介绍

  • 编译时依赖注入:Wire 在编译时解析依赖关系,生成代码以满足依赖。这意味着在运行时没有反射或其他开销,从而提高了性能。

  • 类型安全:Wire 利用 Go 的类型系统,确保依赖关系的正确性。这可以在编译时捕获错误,而不是在运行时。

  • 简单易用:Wire 的 API 设计简单,易于理解和使用。通过明确的配置,可以轻松管理复杂的依赖关系。

  • 生成代码:Wire 使用代码生成的方式创建所需的构造函数和初始化代码。用户只需定义依赖关系,Wire 会自动生成满足这些依赖的代码。

2.2 使用函数解释

  • wire.NewSet 允许你组合多个提供者函数,组织依赖关系。
  • wire.Build 用于定义 Injector 的构建逻辑,自动生成满足依赖关系的代码。

3. 代码示例

  • 存储层 (store/store.go):

    复制代码
    // 定义了一个消息存储接口
    type Store interface {
        Save(msg Message) error
        Get() (Message, error)
    }
    
    // ProvideStore 将 InMemoryStore 绑定到 Store 接口
    func ProvideStore() Store {
        return NewInMemoryStore()
    }
    
    // StoreSet 是 Wire 的 provider set
    var StoreSet = wire.NewSet(
        ProvideStore,
    )
  • 服务层 (service/service.go):

    复制代码
    // MessageService 依赖于 Store 接口
    type MessageService struct {
        store store.Store
    }
    
    // Wire Provider: 告诉 Wire 如何构造 MessageService
    func NewMessageService(s store.Store) *MessageService
  • 应用层 (main.go):

    复制代码
    // MessageApp 依赖于 MessageService
    type MessageApp struct {
        msgService *service.MessageService
    }
    
    // Wire Provider: 告诉 Wire 如何构造 MessageApp
    func NewMessageApp(service *service.MessageService) *MessageApp
  • Wire 配置 (wire.go):

    复制代码
    // 定义依赖注入的规则
    func InitializeMessageApp() (*MessageApp, error) {
        wire.Build(
            store.StoreSet,             // 提供 Store 接口的实现
            service.NewMessageService,  // 提供 MessageService 的构造函数
            NewMessageApp,              // 提供 MessageApp 的构造函数
        )
        return &MessageApp{}, nil       // 这个返回值会被 Wire 生成的代码替换
    }

依赖关系:

  • MessageApp 依赖 → MessageService
  • MessageService 依赖 → Store 接口
  • Store 接口由 InMemoryStore 实现

Wire 的工作流程:

  • 分析 wire.go 中的 InitializeMessageApp 函数

  • 检查所有依赖关系

  • 生成 wire_gen.go 文件,包含了正确顺序的依赖初始化代码

  • 运行时,自动按正确顺序创建和注入所有依赖

    复制代码
    // Code generated by Wire. DO NOT EDIT.
    
    //go:generate go run -mod=mod github.com/google/wire/cmd/wire
    //go:build !wireinject
    // +build !wireinject
    
    package main
    
    import (
        "example/wire/service"
        "example/wire/store"
    )
    
    // Injectors from wire.go:
    
    // InitializeMessageApp 使用 Wire 来注入依赖并初始化应用
    func InitializeMessageApp() (*MessageApp, error) {
        storeStore := store.ProvideStore()
        messageService := service.NewMessageService(storeStore)
        messageApp := NewMessageApp(messageService)
        return messageApp, nil
    }
  • 这种依赖注入方式的优点:

    • 解耦:各组件之间通过接口交互,不直接依赖具体实现

    • 可测试:易于替换模拟实现进行测试

    • 维护性:依赖关系清晰,容易管理

    • 编译时检查:在编译时就能发现依赖配置问题

4. 碎碎念

之前一阵子焦虑 AI 是不是会替代自己,但是换个角度想,如果能更充分的利用 AI,是不是之前消耗的很多时间都可以节省掉,这样就可以做很多有意义的事情啦:

  • 她那个时候还太年轻,不知道所有命运馈赠的礼物,都早已在背后标好了价格。

  • 不要责怪以前的自己, 她那时一个人站在雾里也很迷茫。

  • 纽约的时间比加州时间早3个小时,但加州并没变慢,奥巴马55岁就退休了,但川普70岁才当上总统,世界上每个人本来都有自己的时区,有些人看似走在你前面,有些人看似走在你后面,但其实每个人都有自己的时区和步程,不用嫉妒和嘲笑他们,每个人都在自己的时区里,你也是 。

5. 参考资料

相关推荐
geovindu3 小时前
go: Mediator Pattern
设计模式·golang·中介者模式
MATLAB代码顾问6 小时前
5大智能算法优化标准测试函数对比(Python实现)
开发语言·python
万粉变现经纪人7 小时前
如何解决 pip install llama-cpp-python 报错 未安装 CMake/Ninja 或 CPU 不支持 AVX 问题
开发语言·python·开源·aigc·pip·ai写作·llama
小码哥_常7 小时前
Spring Boot:别再重复造轮子,这些内置功能香麻了
后端
清风明月一壶酒8 小时前
OpenClaw自动处理Word文档全流程
开发语言·c#·word
其实防守也摸鱼8 小时前
CTF密码学综合教学指南--第五章
开发语言·网络·笔记·python·安全·网络安全·密码学
皮皮林5518 小时前
OpenFeign 首次调用卡 3 秒?八年老开发扒透 5 个坑,实战优化到 100ms!
后端
小郑加油9 小时前
python学习Day12:pandas安装与实际运用
开发语言·python·学习
AC赳赳老秦9 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
KuaCpp9 小时前
C++面向对象(速过复习版)
开发语言·c++