概述
Java Spring最重要的特性之一就是强大的依赖注入能力。依赖注入,简单理解就是不写构造器或NewXXX,由框架负责创建出实例。Go崇尚简单清晰,官方并没有很好的依赖注入能力,Google开源的wire是为CDK(Cloud Development Kit)服务的,它基于代码生成而不是常见的运行时注入。
实战
一键安装
go get github.com/google/wire/cmd/wire
只要懂2个基础概念
Provider
“提供者”,顾名思义就是提供给依赖注入的“原料”,可以是NewXXX函数,也可以是wire提供的一些工具函数,例如wire.Bind, wire.Struct, wire.Value, wire.InterfaceValue。
Injector
“注入者”,是我们想要创建出实例的函数,在wire中就是我们指示wire,希望生成的构造函数。
案例代码
基于公开的资料,整理了wire的demo: github.com/luxiaofengl…
只需要在wire.go,所在的路径下运行
wire gen .
即可生成wire_gen.go
wire.go的编写如下:
//go:build wireinject
package demo
import (
"github.com/google/wire"
"gorm.io/gorm"
"io"
"os"
"wire_demo/demo/common"
"wire_demo/demo/dal"
"wire_demo/demo/handler"
"wire_demo/demo/service"
)
func InitializeBroadCast() BroadCast {
wire.Build(NewBroadCast, NewChannel, NewMessage)
return BroadCast{}
}
func BuildInjector() (*Injector, error) {
wire.Build(
NewInjector,
handler.NewProjectHandler,
service.NewProjectService,
wire.Bind(new(dal.IProjectDal), new(*dal.ProjectDal)),
dal.NewProjectDal,
dal.NewQuestionDal,
dal.NewQuestionModelDal,
common.InitGormDB,
)
return new(Injector), nil
}
func BuildInjectorBySet() (*Injector, error) {
wire.Build(
NewInjector,
ProjectSet,
common.InitGormDB,
)
return new(Injector), nil
}
var ProjectSet = wire.NewSet(
handler.NewProjectHandler,
service.NewProjectService,
wire.Bind(new(dal.IProjectDal), new(*dal.ProjectDal)),
dal.NewProjectDal,
dal.NewQuestionDal,
dal.NewQuestionModelDal,
)
func BuildInjectorByStructProvider() (*Injector, error) {
wire.Build(
NewInjector,
handler.NewProjectHandler,
wire.Struct(new(service.ProjectService), "*"),
// interface bind
wire.Bind(new(dal.IProjectDal), new(*dal.ProjectDal)),
dal.NewProjectDal,
dal.NewQuestionDal,
dal.NewQuestionModelDal,
common.InitGormDB,
)
return new(Injector), nil
}
func BuildInjectorClean() (*Injector, func(), error) {
wire.Build(
NewInjector,
handler.NewProjectHandler,
service.NewProjectServiceClean,
wire.Bind(new(dal.IProjectDal), new(*dal.ProjectDal)),
dal.NewProjectDal,
dal.NewQuestionDal,
dal.NewQuestionModelDal,
common.InitGormDB,
)
return new(Injector), nil, nil
}
var ISet = wire.NewSet(wire.InterfaceValue(new(io.Reader), os.Stdin))
func BuildByInterfaceValueProvider() *common.MyReader {
wire.Build(common.NewMyReader, ISet)
return new(common.MyReader)
}
func BuildByValueProvider() *dal.QuestionDal {
wire.Build(
dal.NewQuestionDal,
wire.Value(&gorm.DB{}),
)
return new(dal.QuestionDal)
}