wire

wire ,代码生成器,并不是一个框架。在特殊的go文件中告诉wire类型之间的依赖关系,它会自动帮我们生成代码,帮助我们创建指定类型的对象,并组装它的依赖

模拟 web 项目初始化过程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main  
  
import "fmt"  
  
type DB struct {  
}  
  
type Cache struct {  
}  
  
type UserRepo struct {  
   DB    *DB  
   Cache *Cache  
}  
  
type UserService struct {  
   UserRepo *UserRepo  
}  
  
type App struct {  
   UserService *UserService  
}  
  
func (app *App) Start() {  
   fmt.Println("server starting")  
}  
  
func NewDB() (*DB, func(), error) {  
   db := &DB{}  
   cleanup := func() {  
      fmt.Println("close db connection")  
   }  
   return db, cleanup, nil  
}  
  
func NewCache() *Cache {  
   return &Cache{}  
}  
  
func NewUserRepo(db *DB, cache *Cache) *UserRepo {  
   return &UserRepo{DB: db, Cache: cache}  
}  
  
func NewUserService(userRepo *UserRepo) *UserService {  
   return &UserService{UserRepo: userRepo}  
}  
  
func NewApp(userService *UserService) *App {  
   return &App{UserService: userService}  
}  

不使用 wire

手动 new 方式初始化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
func main() {  
   db, cleanup, err := NewDB()  
   if err != nil {  
      panic(err)  
   }  
   defer cleanup()  
   cache := NewCache()  
   userRepo := NewUserRepo(db, cache)  
   userService := NewUserService(userRepo)  
   app := NewApp(userService)  
   app.Start()  
}

使用 DI

1
go install github.com/google/wire/cmd/wire@latest

创建 wire.go  用于生成代码,申明了最初始的入参和最终的产出物

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
//go:build wireinject  
// +build wireinject  
  
package main  
  
import (  
   "github.com/google/wire"  
)  
  
// InitializeApplication  
func InitializeApplication() (*App, func(), error) {  
   panic(wire.Build(NewDB, NewCache, NewUserRepo, NewUserService, NewApp))  
}
1
wire .

生成对应的依赖关系和初始化过程

在使用的地方调用对应的初始化方法获得产物即可,不需要关心其中的依赖关系

1
2
3
4
5
6
7
8
func main() {  
   app, cleanup, err := InitializeApplication()  
   if err != nil {  
      panic(err)  
   }  
   defer cleanup()  
   app.Start()  
}

wire 在每个 new 方法中支持三个参数,对象,cleanup,error,参数 cleanup 就会在关闭的时候按照依赖的倒序依次进行关闭。

wire 做的事情就是根据你 new 方法的入参和出参,识别了他们之间的依赖关系,生成了对应的初始化代码

ref

https://darjun.github.io/2020/03/02/godailylib/wire/