to options mode

This commit is contained in:
yanghao05
2023-04-27 18:30:39 +08:00
parent 8ae3d19aa9
commit 574736a878
20 changed files with 180 additions and 50 deletions

View File

@@ -7,8 +7,8 @@ import (
"github.com/mojocn/base64Captcha" "github.com/mojocn/base64Captcha"
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"github.com/rogeecn/atom/providers"
"github.com/spf13/viper" "github.com/spf13/viper"
"go.uber.org/dig"
) )
type CaptchaResponse struct { type CaptchaResponse struct {
@@ -22,7 +22,12 @@ type Captcha struct {
captcha *base64Captcha.Captcha captcha *base64Captcha.Captcha
} }
func Provide(conf *Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
var conf Config
if err := o.UnmarshalConfig(&conf); err != nil {
log.Fatal(err)
}
return container.Container.Provide(func() (*Captcha, error) { return container.Container.Provide(func() (*Captcha, error) {
driver := base64Captcha.NewDriverDigit( driver := base64Captcha.NewDriverDigit(
int(conf.Width), int(conf.Width),
@@ -36,7 +41,7 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error {
return &Captcha{ return &Captcha{
captcha: base64Captcha.NewCaptcha(driver, store), captcha: base64Captcha.NewCaptcha(driver, store),
}, nil }, nil
}) }, o.DiOptions()...)
} }
func (c *Captcha) OpenCaptchaTimeOutDuration() time.Duration { func (c *Captcha) OpenCaptchaTimeOutDuration() time.Duration {

View File

@@ -5,6 +5,8 @@ import (
"time" "time"
) )
const DefaultPrefix = "Captcha"
type Config struct { type Config struct {
Long uint // 验证码长度 Long uint // 验证码长度
Width uint // 验证码宽度 Width uint // 验证码宽度

View File

@@ -0,0 +1,32 @@
package config
import (
"github.com/rogeecn/atom/container"
"github.com/spf13/viper"
)
func AutoLoad() *viper.Viper {
v, err := Load("config.toml")
if err != nil {
return nil
}
return v
}
func Load(file string) (*viper.Viper, error) {
v := viper.NewWithOptions(viper.KeyDelimiter("_"))
v.AutomaticEnv()
v.SetConfigFile(file)
if err := v.ReadInConfig(); err != nil {
return nil, err
}
err := container.Container.Provide(func() (*viper.Viper, error) {
return v, nil
})
if err != nil {
return nil, err
}
return v, nil
}

View File

@@ -4,6 +4,8 @@ import (
"fmt" "fmt"
) )
const DefaultPrefix = "MySQL"
// MySQL database config // MySQL database config
type Config struct { type Config struct {
Host string Host string

View File

@@ -4,15 +4,20 @@ import (
"database/sql" "database/sql"
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"github.com/rogeecn/atom/providers"
"github.com/rogeecn/atom/providers/log" "github.com/rogeecn/atom/providers/log"
"go.uber.org/dig"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
) )
func Provide(conf *Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
var conf Config
if err := o.UnmarshalConfig(&conf); err != nil {
return err
}
return container.Container.Provide(func() (*gorm.DB, error) { return container.Container.Provide(func() (*gorm.DB, error) {
if err := createMySQLDatabase(conf.EmptyDsn(), "mysql", conf.CreateDatabaseSql()); err != nil { if err := createMySQLDatabase(conf.EmptyDsn(), "mysql", conf.CreateDatabaseSql()); err != nil {
return nil, err return nil, err
@@ -53,7 +58,7 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error {
sqlDB.SetMaxOpenConns(conf.MaxOpenConns) sqlDB.SetMaxOpenConns(conf.MaxOpenConns)
return db, err return db, err
}, opts...) }, o.DiOptions()...)
} }
// createDatabase 创建数据库 // createDatabase 创建数据库

View File

@@ -4,6 +4,8 @@ import (
"fmt" "fmt"
) )
const DefaultPrefix = "Postgres"
type Config struct { type Config struct {
Username string Username string
Password string Password string

View File

@@ -4,14 +4,19 @@ import (
"log" "log"
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"go.uber.org/dig" "github.com/rogeecn/atom/providers"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
) )
func Provide(conf *Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
var conf Config
if err := o.UnmarshalConfig(&conf); err != nil {
return err
}
return container.Container.Provide(func() (*gorm.DB, error) { return container.Container.Provide(func() (*gorm.DB, error) {
dbConfig := postgres.Config{ dbConfig := postgres.Config{
DSN: conf.DSN(), // DSN data source name DSN: conf.DSN(), // DSN data source name
@@ -36,5 +41,5 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error {
sqlDB.SetMaxOpenConns(conf.MaxOpenConns) sqlDB.SetMaxOpenConns(conf.MaxOpenConns)
return db, err return db, err
}, opts...) }, o.DiOptions()...)
} }

View File

@@ -1,5 +1,7 @@
package sqlite package sqlite
const DefaultPrefix = "SQLite"
type Config struct { type Config struct {
File string File string
} }

View File

@@ -2,14 +2,19 @@ package sqlite
import ( import (
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"go.uber.org/dig" "github.com/rogeecn/atom/providers"
// "gorm.io/driver/sqlite" // "gorm.io/driver/sqlite"
"github.com/glebarez/sqlite" "github.com/glebarez/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
) )
func Provide(conf *Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
var conf Config
if err := o.UnmarshalConfig(&conf); err != nil {
return err
}
return container.Container.Provide(func() (*gorm.DB, error) { return container.Container.Provide(func() (*gorm.DB, error) {
db, err := gorm.Open(sqlite.Open(conf.File), &gorm.Config{}) db, err := gorm.Open(sqlite.Open(conf.File), &gorm.Config{})
if err != nil { if err != nil {
@@ -17,5 +22,5 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error {
} }
return db, err return db, err
}, opts...) }, o.DiOptions()...)
} }

View File

@@ -4,16 +4,16 @@ import (
"time" "time"
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"go.uber.org/dig" "github.com/rogeecn/atom/providers"
"github.com/brianvoe/gofakeit/v6" "github.com/brianvoe/gofakeit/v6"
) )
func Provide(opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
return container.Container.Provide(func() (*gofakeit.Faker, error) { return container.Container.Provide(func() (*gofakeit.Faker, error) {
faker := gofakeit.New(time.Now().UnixNano()) faker := gofakeit.New(time.Now().UnixNano())
gofakeit.SetGlobalFaker(faker) gofakeit.SetGlobalFaker(faker)
return faker, nil return faker, nil
}, opts...) }, o.DiOptions()...)
} }

View File

@@ -4,6 +4,8 @@ import (
"fmt" "fmt"
) )
const ConfigPrefix = "Http"
type Config struct { type Config struct {
Static *string Static *string
Host *string Host *string

View File

@@ -3,42 +3,29 @@ package http
import ( import (
"log" "log"
"github.com/rogeecn/atom/utils/fs"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
const DefaultPrefix = "HTTP" const DefaultPrefix = "Http"
func AutoLoadConfig() *Config { func AutoLoadConfig() *Config {
return LoadConfig("", DefaultPrefix) return LoadConfig("")
} }
func LoadConfig(file, envPrefix string) *Config { func LoadConfig(file string) *Config {
if file == "" { if file == "" {
file = "config.toml" file = "config.toml"
} }
if envPrefix == "" {
envPrefix = DefaultPrefix
}
v := viper.NewWithOptions(viper.KeyDelimiter("_")) v := viper.NewWithOptions(viper.KeyDelimiter("_"))
v.SetEnvPrefix(envPrefix)
v.AutomaticEnv() v.AutomaticEnv()
if !fs.FileExist(file) {
return &Config{}
}
// load file
v.SetConfigFile(file) v.SetConfigFile(file)
if err := v.ReadInConfig(); err != nil { if err := v.ReadInConfig(); err != nil {
log.Fatal(err) log.Fatal(err)
} }
var config Config var config Config
if err := v.Unmarshal(&config); err != nil { if err := v.UnmarshalKey(DefaultPrefix, &config); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@@ -5,9 +5,9 @@ import (
"time" "time"
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"github.com/rogeecn/atom/providers"
"github.com/rogeecn/atom/providers/http" "github.com/rogeecn/atom/providers/http"
"github.com/rogeecn/atom/providers/log" "github.com/rogeecn/atom/providers/log"
"go.uber.org/dig"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@@ -32,7 +32,12 @@ func (e *Service) Serve() error {
return e.Engine.Run(e.conf.PortString()) return e.Engine.Run(e.conf.PortString())
} }
func Provide(cfg *http.Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
var config http.Config
if err := o.UnmarshalConfig(&config); err != nil {
log.Fatal(err)
}
return container.Container.Provide(func() (http.Service, error) { return container.Container.Provide(func() (http.Service, error) {
gin.DefaultWriter = log.LevelWriter{Level: log.InfoLevel} gin.DefaultWriter = log.LevelWriter{Level: log.InfoLevel}
gin.DefaultErrorWriter = log.LevelWriter{Level: log.ErrorLevel} gin.DefaultErrorWriter = log.LevelWriter{Level: log.ErrorLevel}
@@ -53,6 +58,6 @@ func Provide(cfg *http.Config, opts ...dig.ProvideOption) error {
) )
})) }))
return &Service{Engine: engine, conf: cfg}, nil return &Service{Engine: engine, conf: &config}, nil
}, opts...) }, o.DiOptions()...)
} }

View File

@@ -6,6 +6,8 @@ import (
"github.com/rogeecn/atom/providers/log" "github.com/rogeecn/atom/providers/log"
) )
const DefaultKeyPrefix = "JWT"
type Config struct { type Config struct {
SigningKey string // jwt签名 SigningKey string // jwt签名
ExpiresTime string // 过期时间 ExpiresTime string // 过期时间

View File

@@ -6,7 +6,8 @@ import (
"time" "time"
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"go.uber.org/dig" "github.com/rogeecn/atom/providers"
"github.com/rogeecn/atom/providers/log"
jwt "github.com/golang-jwt/jwt/v4" jwt "github.com/golang-jwt/jwt/v4"
"golang.org/x/sync/singleflight" "golang.org/x/sync/singleflight"
@@ -43,13 +44,17 @@ var (
TokenInvalid = errors.New("Couldn't handle this token:") TokenInvalid = errors.New("Couldn't handle this token:")
) )
func Provide(config *Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
var config Config
if err := o.UnmarshalConfig(&config); err != nil {
log.Fatal(err)
}
return container.Container.Provide(func() (*JWT, error) { return container.Container.Provide(func() (*JWT, error) {
return &JWT{ return &JWT{
config: config, config: &config,
SigningKey: []byte(config.SigningKey), SigningKey: []byte(config.SigningKey),
}, nil }, nil
}, opts...) }, o.DiOptions()...)
} }
func (j *JWT) CreateClaims(baseClaims BaseClaims) *Claims { func (j *JWT) CreateClaims(baseClaims BaseClaims) *Claims {

View File

@@ -1,5 +1,7 @@
package log package log
const DefaultKeyPrefix = "Log"
type Config struct { type Config struct {
Level Level Level Level
} }

View File

@@ -2,20 +2,25 @@ package log
import ( import (
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"github.com/rogeecn/atom/providers"
"go.uber.org/dig"
"go.uber.org/zap" "go.uber.org/zap"
) )
func Provide(config *Config, opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
logger, err := newZapLogger(config) var config Config
if err := o.UnmarshalConfig(&config); err != nil {
return err
}
logger, err := newZapLogger(&config)
if err != nil { if err != nil {
return err return err
} }
defaultLogger = logger defaultLogger = logger
return container.Container.Provide(func() (*Logger, error) { return container.Container.Provide(func() (*Logger, error) {
return defaultLogger, nil return defaultLogger, nil
}, opts...) }, o.DiOptions()...)
} }
var defaultLogger *Logger var defaultLogger *Logger

62
providers/options.go Normal file
View File

@@ -0,0 +1,62 @@
package providers
import (
"github.com/spf13/viper"
"go.uber.org/dig"
)
type Options struct {
Config *viper.Viper
ConfigPrefix string
Name string
Group string
}
type Option func(o *Options)
func New(opts ...Option) *Options {
o := &Options{}
for _, opt := range opts {
opt(o)
}
return o
}
func (o *Options) UnmarshalConfig(config interface{}) error {
return o.Config.UnmarshalKey(o.ConfigPrefix, &config)
}
func (o *Options) DiOptions() []dig.ProvideOption {
options := []dig.ProvideOption{}
if o.Name != "" {
options = append(options, dig.Name(o.Name))
}
if o.Group != "" {
options = append(options, dig.Group(o.Group))
}
return options
}
func WithConfig(config *viper.Viper) Option {
return func(o *Options) {
o.Config = config
}
}
func WithName(name string) Option {
return func(o *Options) {
o.Name = name
}
}
func WithGroup(group string) Option {
return func(o *Options) {
o.Group = group
}
}
func WithConfigPrefix(prefix string) Option {
return func(o *Options) {
o.ConfigPrefix = prefix
}
}

View File

@@ -2,12 +2,12 @@ package single_flight
import ( import (
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"go.uber.org/dig" "github.com/rogeecn/atom/providers"
"golang.org/x/sync/singleflight" "golang.org/x/sync/singleflight"
) )
func Provide(opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
return container.Container.Provide(func() (*singleflight.Group, error) { return container.Container.Provide(func() (*singleflight.Group, error) {
return &singleflight.Group{}, nil return &singleflight.Group{}, nil
}, opts...) }, o.DiOptions()...)
} }

View File

@@ -2,7 +2,7 @@ package uuid
import ( import (
"github.com/rogeecn/atom/container" "github.com/rogeecn/atom/container"
"go.uber.org/dig" "github.com/rogeecn/atom/providers"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
) )
@@ -11,12 +11,12 @@ type Generator struct {
generator uuid.Generator generator uuid.Generator
} }
func Provide(opts ...dig.ProvideOption) error { func Provide(o *providers.Options) error {
return container.Container.Provide(func() (*Generator, error) { return container.Container.Provide(func() (*Generator, error) {
return &Generator{ return &Generator{
generator: uuid.DefaultGenerator, generator: uuid.DefaultGenerator,
}, nil }, nil
}) }, o.DiOptions()...)
} }
func (u *Generator) MustGenerate() string { func (u *Generator) MustGenerate() string {