美文网首页
golang wire 依赖注入

golang wire 依赖注入

作者: 哆啦在这A梦在哪 | 来源:发表于2021-10-19 15:35 被阅读0次

wire执行过程:

一.假设需要定义多个有依赖的启动项(代码如下)

package main
import ("fmt")

type Message string

func NewMessage() Message {
    return Message("Hi there!")
}

type Event struct {
    Greeter Greeter // <- adding a Greeter field
}

func NewEvent(g Greeter) Event {
    return Event{Greeter: g}
}

func (e Event) Start() {
    msg := e.Greeter.Greet()
    fmt.Println(msg)
}

func NewGreeter(m Message) Greeter {
    return Greeter{Message: m}
}

type Greeter struct {
    Message Message // <- adding a Message field
}

func (g Greeter) Greet() Message {
    return g.Message
}

func main() {
    // message := NewMessage()
    // greeter := NewGreeter(message)
    // event := NewEvent(greeter)
    // event.Start()
//如果没依赖注入,就需要写上面这些代码,现在用一个 InitializeEvent 方法包含这些,而这个方法让他自动生成
    e := InitializeEvent()
    e.Start()
}

二。新建一个 wire.go 文件,名称不一定用这个,但是为了规范和约束,一般都用这个。内容如下。

//go:build wireinject
// +build wireinject

package main

import "github.com/google/wire"

func InitializeEvent() Event {
    wire.Build(NewEvent, NewGreeter, NewMessage)
    return Event{}
}
//这个是简写,直接用 panic 包裹起来即可,因为不需要检查,所以不需要反馈
// func InitializeEvent() Event {
//  panic(wire.Build(NewEvent, NewMessage, NewGreeter))
// }

三。执行 wire 命令,自动生成 wire_gen.go 文件,内容如下:

// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package main

// Injectors from wire.go:

func InitializeEvent() Event {
    message := NewMessage()
    greeter := NewGreeter(message)
    event := NewEvent(greeter)
    return event
}

四。结果、自动生成了第一步中繁杂的依赖定义。

五。注意点:

5.1、Injector: 由wire自动生成的函数。

函数内部会按根据依赖顺序调用相关 privoder 。

5.2、wire.Build 生成函数

我们在 wire.go (文件名非强制,但一般约定如此)文件中定义 injector 函数签名。然后在函数体中调用wire.Build ,并以所需 provider 作为参数(无须考虑顺序,就是与参数顺序无关)。

5.3、wire.go中的函数返回值,编译

由于wire.go中的函数并没有真正返回值,为避免编译器报错, 简单地用panic函数包装起来即可。不用担心执行时报错, 因为它不会实际运行,只是用来生成真正的代码的依据。

5.4、build*** wireinject 标签含义

wire.go 第一行 // *+build* wireinject ,这个 build tag 确保在常规编译时忽略 wire.go 文件(因为常规编译时不会指定 wireinject 标签)。

5.5、build*** !wireinject 标签含义

与之相对的是 wire_gen.go 中的 //*+build* !wireinject 。两组对立的 build tag 保证在任意情况下, wire.go 与 wire_gen.go 只有一个文件生效, 避免了“UserLoader 方法被重复定义”的编译错误.

5.6、简单的初始化过程 ,error 处理

自动生成的 UserLoader 代码包含了 error 处理。与我们手写代码几乎相同。对于这样一个简单的初始化过程, 手写也不算麻烦。但当组件数达到几十、上百甚至更多时, 自动生成的优势就体现出来了。

5.7、go generate 或 wire 生成

要触发“生成”动作有两种方式:go generate 或 wire 。前者仅在 wire_gen.go 已存在的情况下有效(因为 wire_gen.go 的第三行 //*go:generate* wire),而后者在任何时候都有可以调用。并且后者有更多参数可以对生成动作进行微调, 所以建议始终使用 wire 命令。

相关文章

网友评论

      本文标题:golang wire 依赖注入

      本文链接:https://www.haomeiwen.com/subject/wupmoltx.html