go wire 入门连载二:单体应用注入项目

140 阅读2分钟

更方便的在微信公众号阅读文章可以关注公众号:海生的go花园

image.png

之前写过一篇文章,主要是介绍wire的多个依赖注入实现 go wire 入门

实际使用中,很多人用的是框架,比如 kratos是单体应用,这里再着重介绍一下,这方面的使用。

一、wire介绍

wire 依赖注入 有两个核心概念 providers 和 injectors 。 语法如下: wire.Build(provide1, provide2,***)

  • providers,主要是生成对象(结构图)的普通方法。这些方法接收所需依赖作为参数,创建对象(结构图)并将其返回。
  • injectors,是注入。

二、定义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。