go wire 入門連載二:單體應用注入項目

之前寫過一篇文章,主要是介紹 wire 的多個依賴注入實現 go wire 入門

實際使用中,很多人用的是框架,比如 kratos 是單體應用,這裏再着重介紹一下,這方面的使用。

一、wire 介紹

wire 依賴注入 有兩個核心概念 providers 和 injectors 。
語法如下:

wire.Build(provide1, provide2,***)

二、定義 providers

1、最簡單的 provider,一個函數 NewUser 生成一個 User,沒有參數。

package user

type User struct {
    Name string
}

func NewUser() User {
    return User{Name: "haha"}
}

2、有一個參數的 provider,一個函數 NewRepository 生成一個 Repository,參數 User。

package user


type Repository struct {
    Name string
}

func NewRepository(u User) Repository {
    return Repository{Name: u.Name}
}

3、有兩個參數的 provider,一個函數 NewService 生成一個 Service,參數 ctx,repo。

package user

import "context"

type Service struct {
    Name string
}

func NewService(ctx context.Context, repo Repository) (Service, error) {
    return Service{Name: repo.Name}, nil
}

4、多個 provider 可以組成一個 provider 集合

package user

import "github.com/google/wire"

var SuperSet = wire.NewSet(NewUser, NewRepository, NewService)

全部的代碼如下:

package user

import (
    "context"
    "github.com/google/wire"
)

type User struct {
    Name string
}

func NewUser() User {
    return User{Name: "haha"}
}

type Repository struct {
    Name string
}

func NewRepository(u User) Repository {
    return Repository{Name: u.Name}
}

type Service struct {
    Name string
}

func NewService(ctx context.Context, repo Repository) (Service, error) {
    return Service{Name: repo.Name}, nil
}

var SuperSet = wire.NewSet(NewUser, NewRepository, NewService)

二、injectors 注入

一個單體應用,有一個唯一的依賴注入入口,比如下面我們寫的 initApp,我們只需要使用
wire.Build 函數,注入需要使用的 providers 就可以了。

//go:build wireinject
// +build wireinject

package user

import (
    "context"
    "github.com/google/wire"
)

func initApp(ctx context.Context) (Service, error) {
    wire.Build(SuperSet)
    return Service{}, nil
}

執行

➜ wire

生成了 wire_gen.go 使用 tree 命令生成樹狀目錄:

➜  tree
.
├── user.go
├── wire.go
└── wire_gen.go

查看一下 wire_gen.go

// Code generated by Wire. DO NOT EDIT.

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

package user

import (
    "context"
)

// Injectors from wire.go:

func initApp(ctx context.Context) (Service, error) {
    user := NewUser()
    repository := NewRepository(user)
    service, err := NewService(ctx, repository)
    if err != nil {
        return Service{}, err
    }
    return service, nil
}

這個文件幫我們生成了
NewUser()
NewRepository(user)
NewService(ctx, repository)
我們可以在其他地方調用 wire_gen.go 裏面的 initApp。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/pFZCHtrIG9YOQxyIaWSfJA