diff --git a/providers/captcha/captcha.go b/providers/captcha/captcha.go index 5fca0e6..ae1b824 100644 --- a/providers/captcha/captcha.go +++ b/providers/captcha/captcha.go @@ -7,8 +7,8 @@ import ( "github.com/mojocn/base64Captcha" "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers" "github.com/spf13/viper" - "go.uber.org/dig" ) type CaptchaResponse struct { @@ -22,7 +22,12 @@ type Captcha struct { 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) { driver := base64Captcha.NewDriverDigit( int(conf.Width), @@ -36,7 +41,7 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error { return &Captcha{ captcha: base64Captcha.NewCaptcha(driver, store), }, nil - }) + }, o.DiOptions()...) } func (c *Captcha) OpenCaptchaTimeOutDuration() time.Duration { diff --git a/providers/captcha/config.go b/providers/captcha/config.go index 7ce78bf..4349f69 100644 --- a/providers/captcha/config.go +++ b/providers/captcha/config.go @@ -5,6 +5,8 @@ import ( "time" ) +const DefaultPrefix = "Captcha" + type Config struct { Long uint // 验证码长度 Width uint // 验证码宽度 diff --git a/providers/config/config.go b/providers/config/config.go new file mode 100644 index 0000000..3bdf21a --- /dev/null +++ b/providers/config/config.go @@ -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 +} diff --git a/providers/database/mysql/config.go b/providers/database/mysql/config.go index 8cc5b31..6b25139 100755 --- a/providers/database/mysql/config.go +++ b/providers/database/mysql/config.go @@ -4,6 +4,8 @@ import ( "fmt" ) +const DefaultPrefix = "MySQL" + // MySQL database config type Config struct { Host string diff --git a/providers/database/mysql/mysql.go b/providers/database/mysql/mysql.go index ea0a1fb..ff55777 100644 --- a/providers/database/mysql/mysql.go +++ b/providers/database/mysql/mysql.go @@ -4,15 +4,20 @@ import ( "database/sql" "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers" "github.com/rogeecn/atom/providers/log" - "go.uber.org/dig" "gorm.io/driver/mysql" "gorm.io/gorm" "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) { if err := createMySQLDatabase(conf.EmptyDsn(), "mysql", conf.CreateDatabaseSql()); err != nil { return nil, err @@ -53,7 +58,7 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error { sqlDB.SetMaxOpenConns(conf.MaxOpenConns) return db, err - }, opts...) + }, o.DiOptions()...) } // createDatabase 创建数据库 diff --git a/providers/database/postgres/config.go b/providers/database/postgres/config.go index 02f070f..2d12c32 100755 --- a/providers/database/postgres/config.go +++ b/providers/database/postgres/config.go @@ -4,6 +4,8 @@ import ( "fmt" ) +const DefaultPrefix = "Postgres" + type Config struct { Username string Password string diff --git a/providers/database/postgres/postgres.go b/providers/database/postgres/postgres.go index c581fe8..5982b97 100644 --- a/providers/database/postgres/postgres.go +++ b/providers/database/postgres/postgres.go @@ -4,14 +4,19 @@ import ( "log" "github.com/rogeecn/atom/container" - "go.uber.org/dig" + "github.com/rogeecn/atom/providers" "gorm.io/driver/postgres" "gorm.io/gorm" "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) { dbConfig := postgres.Config{ DSN: conf.DSN(), // DSN data source name @@ -36,5 +41,5 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error { sqlDB.SetMaxOpenConns(conf.MaxOpenConns) return db, err - }, opts...) + }, o.DiOptions()...) } diff --git a/providers/database/sqlite/config.go b/providers/database/sqlite/config.go index fdff74b..488836e 100755 --- a/providers/database/sqlite/config.go +++ b/providers/database/sqlite/config.go @@ -1,5 +1,7 @@ package sqlite +const DefaultPrefix = "SQLite" + type Config struct { File string } diff --git a/providers/database/sqlite/sqlite.go b/providers/database/sqlite/sqlite.go index c4b64ad..4825595 100644 --- a/providers/database/sqlite/sqlite.go +++ b/providers/database/sqlite/sqlite.go @@ -2,14 +2,19 @@ package sqlite import ( "github.com/rogeecn/atom/container" - "go.uber.org/dig" + "github.com/rogeecn/atom/providers" // "gorm.io/driver/sqlite" "github.com/glebarez/sqlite" "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) { db, err := gorm.Open(sqlite.Open(conf.File), &gorm.Config{}) if err != nil { @@ -17,5 +22,5 @@ func Provide(conf *Config, opts ...dig.ProvideOption) error { } return db, err - }, opts...) + }, o.DiOptions()...) } diff --git a/providers/faker/faker.go b/providers/faker/faker.go index e9a639a..d7d093e 100644 --- a/providers/faker/faker.go +++ b/providers/faker/faker.go @@ -4,16 +4,16 @@ import ( "time" "github.com/rogeecn/atom/container" - "go.uber.org/dig" + "github.com/rogeecn/atom/providers" "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) { faker := gofakeit.New(time.Now().UnixNano()) gofakeit.SetGlobalFaker(faker) return faker, nil - }, opts...) + }, o.DiOptions()...) } diff --git a/providers/http/config.go b/providers/http/config.go index 16dc929..f70210f 100644 --- a/providers/http/config.go +++ b/providers/http/config.go @@ -4,6 +4,8 @@ import ( "fmt" ) +const ConfigPrefix = "Http" + type Config struct { Static *string Host *string diff --git a/providers/http/env.go b/providers/http/env.go index 2f84fc4..f9c48e8 100644 --- a/providers/http/env.go +++ b/providers/http/env.go @@ -3,42 +3,29 @@ package http import ( "log" - "github.com/rogeecn/atom/utils/fs" "github.com/spf13/viper" ) -const DefaultPrefix = "HTTP" +const DefaultPrefix = "Http" func AutoLoadConfig() *Config { - return LoadConfig("", DefaultPrefix) + return LoadConfig("") } -func LoadConfig(file, envPrefix string) *Config { +func LoadConfig(file string) *Config { if file == "" { file = "config.toml" } - if envPrefix == "" { - envPrefix = DefaultPrefix - } - v := viper.NewWithOptions(viper.KeyDelimiter("_")) - - v.SetEnvPrefix(envPrefix) v.AutomaticEnv() - - if !fs.FileExist(file) { - return &Config{} - } - - // load file v.SetConfigFile(file) if err := v.ReadInConfig(); err != nil { log.Fatal(err) } var config Config - if err := v.Unmarshal(&config); err != nil { + if err := v.UnmarshalKey(DefaultPrefix, &config); err != nil { log.Fatal(err) } diff --git a/providers/http/gin/engine.go b/providers/http/gin/engine.go index 0f26c22..d883270 100644 --- a/providers/http/gin/engine.go +++ b/providers/http/gin/engine.go @@ -5,9 +5,9 @@ import ( "time" "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers" "github.com/rogeecn/atom/providers/http" "github.com/rogeecn/atom/providers/log" - "go.uber.org/dig" "github.com/gin-gonic/gin" ) @@ -32,7 +32,12 @@ func (e *Service) Serve() error { 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) { gin.DefaultWriter = log.LevelWriter{Level: log.InfoLevel} 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 - }, opts...) + return &Service{Engine: engine, conf: &config}, nil + }, o.DiOptions()...) } diff --git a/providers/jwt/config.go b/providers/jwt/config.go index ef6aadd..f352913 100644 --- a/providers/jwt/config.go +++ b/providers/jwt/config.go @@ -6,6 +6,8 @@ import ( "github.com/rogeecn/atom/providers/log" ) +const DefaultKeyPrefix = "JWT" + type Config struct { SigningKey string // jwt签名 ExpiresTime string // 过期时间 diff --git a/providers/jwt/jwt.go b/providers/jwt/jwt.go index ee37bfe..7965005 100644 --- a/providers/jwt/jwt.go +++ b/providers/jwt/jwt.go @@ -6,7 +6,8 @@ import ( "time" "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" "golang.org/x/sync/singleflight" @@ -43,13 +44,17 @@ var ( 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 &JWT{ - config: config, + config: &config, SigningKey: []byte(config.SigningKey), }, nil - }, opts...) + }, o.DiOptions()...) } func (j *JWT) CreateClaims(baseClaims BaseClaims) *Claims { diff --git a/providers/log/config.go b/providers/log/config.go index f56bb95..b58c6c3 100644 --- a/providers/log/config.go +++ b/providers/log/config.go @@ -1,5 +1,7 @@ package log +const DefaultKeyPrefix = "Log" + type Config struct { Level Level } diff --git a/providers/log/logger.go b/providers/log/logger.go index c3d0e4a..d6decac 100644 --- a/providers/log/logger.go +++ b/providers/log/logger.go @@ -2,20 +2,25 @@ package log import ( "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers" - "go.uber.org/dig" "go.uber.org/zap" ) -func Provide(config *Config, opts ...dig.ProvideOption) error { - logger, err := newZapLogger(config) +func Provide(o *providers.Options) error { + var config Config + if err := o.UnmarshalConfig(&config); err != nil { + return err + } + + logger, err := newZapLogger(&config) if err != nil { return err } defaultLogger = logger return container.Container.Provide(func() (*Logger, error) { return defaultLogger, nil - }, opts...) + }, o.DiOptions()...) } var defaultLogger *Logger diff --git a/providers/options.go b/providers/options.go new file mode 100644 index 0000000..1d74f0c --- /dev/null +++ b/providers/options.go @@ -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 + } +} diff --git a/providers/single_flight/flight.go b/providers/single_flight/flight.go index 02d3dc1..cc04434 100644 --- a/providers/single_flight/flight.go +++ b/providers/single_flight/flight.go @@ -2,12 +2,12 @@ package single_flight import ( "github.com/rogeecn/atom/container" - "go.uber.org/dig" + "github.com/rogeecn/atom/providers" "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 &singleflight.Group{}, nil - }, opts...) + }, o.DiOptions()...) } diff --git a/providers/uuid/uuid.go b/providers/uuid/uuid.go index ad7affa..37321c2 100644 --- a/providers/uuid/uuid.go +++ b/providers/uuid/uuid.go @@ -2,7 +2,7 @@ package uuid import ( "github.com/rogeecn/atom/container" - "go.uber.org/dig" + "github.com/rogeecn/atom/providers" "github.com/gofrs/uuid" ) @@ -11,12 +11,12 @@ type Generator struct { generator uuid.Generator } -func Provide(opts ...dig.ProvideOption) error { +func Provide(o *providers.Options) error { return container.Container.Provide(func() (*Generator, error) { return &Generator{ generator: uuid.DefaultGenerator, }, nil - }) + }, o.DiOptions()...) } func (u *Generator) MustGenerate() string {