box

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2023 License: Apache-2.0 Imports: 21 Imported by: 0

README

Box - 容器库

box 库提供了一个全局的依赖注入容器,在初始化阶段注册你的所有依赖,在Build阶段,根据依赖关系,递归构建依赖

| 注意:依赖注入容器只支持单例模式,如果需要多例,可注册一个类型的Manager,实现多例

[toc]

快速开始

package main

import (
	"github.com/daemtri/di/box"
	"github.com/daemtri/di/logx"
)

log = logx.GetLogger("main")

func main() {
	// 使用 box.Provide 注入类型构造器
	// 参数需要实现 box.Builder[T] 接口
	box.Provide[*Mysql.Client](&mysql.Builder{}, box.WithFlagPrefix("mysql"))
	// app.ServerBuilder可通过 di.Must[*mysql.Client](ctx) 获取mysql依赖
	box.Provide[*app.Server](&app.ServerBuilder{})

	// 构建依赖,Build只能执行一次
	srv, err := box.Build[*app.Server](context.TODO())
	if err != nil {
		log.Panic("build error", "error", err)
	}
	srv.Run()
}

Provide 语法糖

使用 ProvideFunc 注入构造函数
package main

import (
	"flag"
	"github.com/daemtri/di/box"
)

type Server struct {
	mysql *mysql.Client
}

func (s *Server) Run() {}

// NewServer Option由Build函数使用发射创建,不需要Provide
// ServerRunOption 需要实现接口
func NewServer(ctx box.Context) (*Server, error) {
	// 使用box.Must获取依赖
	mysqlClient := box.Must[*mysql.Client](ctx)
	return &Server{mysql: mysqlClient}, nil
}

func main() {
	// ProvideFunc 注入构造函数
	// 参数签名为: func(box.Context) (T, error)
	box.ProvideFunc[*Server](NewServer)
}
使用 ProvideOptionFunc 注入带Option的构造函数
package main

import (
	"flag"
	"github.com/daemtri/di/box"
)

type ServerRunOption struct {
	Addr string
}

func (s *ServerRunOption) AddFlags(fs *flag.FlagSet) {
	fs.StringVar(&addr, "addr", ":80", "服务监听地址")
}

func (s *ServerRunOption) ValidateFlags() error {
	// 验证 addr 是否合法
	return nil
}

type Server struct {
	mysql *mysql.Client
}
 
func (s *Server) Run() {}

// NewServer Option由Build函数使用发射创建,不需要Provide
// ServerRunOption 需要实现接口
func NewServer(ctx box.Context, opt *ServerRunOption) (*Server, error) {
	// 使用box.Must获取依赖
	mysqlClient := box.Must[*mysql.Client](ctx)
	return &Server{mysql: mysqlClient}, nil
}

func main() {
	// ProvideOptionFunc 注入构造函数
	// 参数签名为: func(box.Context) (T, error)
	box.ProvideOptionFunc[*Server](NewServer)
}
使用 ProvideInject 注入动态参数构造函数 (推荐)
package main

import (
	"github.com/daemtri/di/box"
)

type ServerRunOption struct {
	Addr string `flag:"addr" default:":80" usage:"服务监听地址" validate:"host_port"`
}

type Server struct {
	ctx   context.Context
	mysql *mysql.Client
}

func (s *Server) Run() {}

// NewServer context.Context,ServerRunOption  不需要Provide,由Build函数传入
// *mysql.Client 需要Provide后,才能获取到
func NewServer(ctx context.Context, mysqlClient *mysql.Client, opt *ServerRunOption) (*Server, error) {
	return &Server{ctx ctx, mysql: mysqlClient}, nil
}

func main() {
	// ProvideInject 注入自动构造函数
	// mysql.NewClient仍然是一个函数, 其签名为: func(arg1 arg1Type ...) (T, error)
	box.ProvideInject[*Server](NewServer)
}
使用 ProvideInstance 直接注入对象
package main

import (
	"github.com/daemtri/di/box"
)

type Server struct {
	Addr string `flag:"addr" default:":80" usage:"服务监听地址" validate:"host_port"`

	Ctx   context.Context `inject:"exists"` //  存在时注入
	Mysql *mysql.Client   `inject:"must"`   // 必须注入
}

func (s *Server) Run() {}

func main() {
	box.ProvideInstance[*Server](&Server{})
}

参数说明

-config 指定参数路径
-print-config 打印当前使用的参数配置

FAQ

使用box.WithFlagPrecix("server","run")设置类型的参数前缀避免多个类型参数冲突
使用box.WithName("name")支持Provide多个相同类型
ProvideInject和ProvideInstance如何传递命名参数?
使用box.WithOverride()覆盖已经Provided的类型

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bootstrap

func Bootstrap[T Runable](opts ...BuildOption) error

Bootstrap use to build and run a object it will block until the object is stopped

func Build

func Build[T any](ctx context.Context, opts ...BuildOption) (T, error)

Build 递归构建对象以及对象的依赖 注意:Build 只能被调用一次,否则会引发重复注册配置文件以及重复解析参数的Panic

func Default

func Default() di.Registry

Default 返回默认di.Registry

func EncodeFlags

func EncodeFlags(w io.Writer) (err error)

EncodeFlags 保存已经加载的配置到文件中 format: yaml

func FlagSet

func FlagSet(name ...string) *flag.FlagSet

func Invoke

func Invoke[T any](ctx context.Context) T

func OptionFunc

func OptionFunc[T, K any](fn func(ctx context.Context, option K) (T, error)) *di.InjectBuilder[T, K]

func Provide

func Provide[T any](fn any, opts ...Option)

Provide 实现智能提供数据和注入数据的功能 fn函数必须返回 (T,error) 或者 (X, error),X 实现了T接口

func SetConfig

func SetConfig(items []config.ConfigItem, source flagx.Source) error

SetConfig 设置配置

func SetConfigLoader

func SetConfigLoader(defaultFile string, fn func(configFile string) ([]config.ConfigItem, error))

func SetDefaultConfigFile

func SetDefaultConfigFile(file string)

SetDefaultConfigFile

func SetEnvPrefix

func SetEnvPrefix(prefix string)

Types

type BuildOption

type BuildOption interface {
	// contains filtered or unexported methods
}

func UseInit

func UseInit(fn ...func(context.Context) error) BuildOption

type Builder

type Builder[T any] interface {
	Build(ctx context.Context) (T, error)
}

type ConfigLoader

type ConfigLoader interface {
	Load(ctx context.Context, setter func([]jsonconfig.ConfigItem)) error
}

type Option

type Option interface {
	// contains filtered or unexported methods
}

func WithFlags

func WithFlags(prefix string) Option

func WithName

func WithName(name string) Option

func WithOverride

func WithOverride() Option

func WithSelect

func WithSelect[T any](name string) Option

WithSelect 仅供在ProvideInject时使用,可以指定注入某个类型的名字

type Retrofiter

type Retrofiter interface {
	Retrofit() error
}

Retrofiter 定义了一个可以重新构建对象的接口

type Runable

type Runable interface {
	Run(ctx context.Context) error
}

Runable defined a object that can be run

Directories

Path Synopsis
config

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL