infra一个golang实现的简单易用的‘依赖’注入框架

VogtEmma 发布于5月前
0 条问题

项目地址: infra

1. infra功能介绍

infra是一个Golang实现的极其简单的依赖注入框架,使用Yaml作为配置文件。支持 组件配置 , 组件扩展

目前支持的组件

Gin:https://github.com/anypick/infra-gin

Logrus:https://github.com/anypick/infra-logrus

MySQL:https://github.com/anypick/infra-mysql

Redis:https://github.com/anypick/infra-redis

RabbitMQ:https://github.com/anypick/infra-rabbit

GRPC:开发中

2. infra文件介绍

【starter.go】

  1. 定义接口 typ Starter interface{...} ,所有的自定义的Starter都要实现这个接口,这里已经有一个自定义实现了 type BaseStarter struct{} ,当你定义一个属于自己的Starter的时候可以直接组合该结构体,像下面这样,这样你就不需要去实现所有的方法了
type MyStarter struct {
  infra.BaseStarter
}
  1. 定义结构体 type starterRegister struct{...} ,用于存储你自定义的 Starter ,这些Starter有的是阻塞的(如 Gin , Grpc ),阻塞启动优先级要比非阻塞优先级低,当有多个阻塞Starter,只有最后一个可以阻塞整个程序,其他的应该使用协程去运行。

【boot.go】

  1. 定义结构体 type BootApplication struct{...} ,对于 Starter 的启动,需要经历 Init , Start , Setup 三个阶段,所以这里使用了 模板设计模式

【initializer.go】

  1. 定义接口 type Initializer interface {...} ,对于业务代码中实例(例如Controller层),不希望使用 typ Starter interface{...} 这个接口,我们可以实现这个接口。这里还有 type InitializerRegister struct{} 结构体,用于存储业务代码中实例。
  2. type BaseInitializerStarter struct{} 这是一个 Starter ,负责统一调用业务实例

【utils/】:定义一些工具类。

【base/】:定义 YamlStarter

对于这个YamlStarter使用 装饰者设计模式 支持用户扩展自定义配置。

3. infra使用

$ go get github.com/anypick/infra

1. 自定义Starter

具体代码请参照github源码: infra-gin

这里以整合Gin框架为例,关键点:

【gin.go】

  1. 组合 BaseStarter
type GinStarter struct {
	infra.BaseStarter
}
  1. 对外暴露gin实例(单例)
var ginEngine *gin.Engine

// 对外暴露
func Gin() *gin.Engine {
	return ginEngine
}

2. 自定义Starter

具体代码参照github源码: infra-logrus

这个自定义Stater整合logrus框架为例

【logrus.go】

和 gin.go 一样,目的都是组合 infra.BaseStarter 实现 Starter接口

这里主要关注点: 【logrus_config.go】

定义一个配置log的配置结构体, Prefix ,为必须字段,主要作用是用来获取改结构体。这个结构体实现了infra项目中 type YamlConfig interface{} 接口(在目录base/props/container/下)。

// 日志配置
type LogConfig struct {
	Prefix       string
	Level        string `yaml:"level"`
	LogFileName  string `yaml:"logFileName"`
	FilePath     string `yaml:"filePath"`
	MaxAge       int    `yaml:"maxAge"`
	RotationTime int    `yaml:"rotationTime"`
}

func (l *LogConfig) ConfigAdd(config map[interface{}]interface{}) {
	l.Level = fmt.Sprintf("%v", config["level"])
	l.LogFileName = fmt.Sprintf("%v", config["logFileName"])
	l.FilePath = fmt.Sprintf("%v", config["filePath"])
	l.MaxAge = config["maxAge"].(int)
	l.RotationTime = config["rotationTime"].(int)
}

使用init方法,将该结构体放入 YamlContainer 中

func init() {
	container.RegisterYamContainer(&LogConfig{Prefix: YamlPrefix})
}

4.整合

项目地址: infra-example

$ go get github.com/anypick/infra
$ go get github.com/anypick/infra-logrus
$ go get github.com/anypick/infra-gin

前面我们已经定义好了两个starter,现在来新建一个项目 infra-example ,对于项目的目录我喜欢这样:

├── README.md
├── app.go
├── brun
│   └── main.go
├── go.mod
├── go.sum
├── resources
│   └── application.yml
└── src
    └── GinExample.go

application.yml :为配置文件目录

main.go :程序启动类

app.go :负责注册需要的实例

src :定义业务代码

【app.go】

package example

import (
	"github.com/anypick/infra"
	"github.com/anypick/infra-gin"
	"github.com/anypick/infra-logrus"
	"github.com/anypick/infra/base/props/container"
)

func init() {
  // YamlStarter,是必须要注册的Starter
	infra.Register(&container.YamlStarter{})
	infra.Register(&baselog.LogrusStarter{})
	infra.Register(&basegin.GinStarter{})

  // BaseInitializerStarter也是必须要注册的Starter
	infra.Register(&infra.BaseInitializerStarter{})
}

【GinExample.go】

这是一个Controller,需要实现接口

// 用于业务的代码的注入,例如Dao层,Service层,Controller层
type Initializer interface {
	Init()
}

【main.go】

GinExample.go中有一个init函数,需要在这里引入

import (
  // 引入app.go init函数
	_ "example"
  // 引入GinExample.go init函数
	_ "example/src"
	"flag"
	"fmt"
	"github.com/anypick/infra"
	"github.com/anypick/infra/base/props"
	"github.com/anypick/infra/utils/common"
)

func main() {
	// 生成网站:http://patorjk.com/software/taag
	banner := `...`
	fmt.Println(banner)
	profile := flag.String("profile", "", "环境信息")
	flag.Parse()
	resource := ""
	if common.StrIsBlank(*profile) {
		resource = "resources/application.yml"
	} else {
		resource = fmt.Sprintf("resources/application-%s.yml", *profile)
	}
	yamlConf := props.NewYamlSource(resource)
	application := infra.New(*yamlConf)
	application.Start()
}

查看原文: infra一个golang实现的简单易用的‘依赖’注入框架

  • crazybird
  • ticklishmeercat
  • bluepeacock
  • purpleduck
  • heavygoose
  • whitefrog
  • blackwolf
  • goldengoose
需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。