121 lines
2.4 KiB
Go
121 lines
2.4 KiB
Go
package modules
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/mitchellh/mapstructure"
|
|
"go.uber.org/fx"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type ModuleConfiguration interface {
|
|
Extract(destination any) error
|
|
}
|
|
|
|
var registry map[string]Module = map[string]Module{}
|
|
|
|
func RegisterModule(module Module) {
|
|
registry[module.Name()] = module
|
|
}
|
|
|
|
func GetModule(name string) Module {
|
|
return registry[name]
|
|
}
|
|
|
|
type Module interface {
|
|
Name() string
|
|
|
|
Create(id string, moduleConfiguration map[string]interface{}) (fx.Option, error)
|
|
}
|
|
|
|
type ModuleFactoryContext interface {
|
|
Id() string
|
|
Kind() string
|
|
|
|
NameTag() string
|
|
GroupTag() string
|
|
|
|
ConfigureLogger(logger *zap.Logger) *zap.Logger
|
|
|
|
ExtractConfig(destination any) error
|
|
AddOption(option fx.Option)
|
|
|
|
Provide(constructors ...interface{})
|
|
Invoke(funcs ...interface{})
|
|
}
|
|
|
|
type simpleFactoryContext struct {
|
|
id string
|
|
kind string
|
|
config map[string]interface{}
|
|
options []fx.Option
|
|
}
|
|
|
|
func (s *simpleFactoryContext) Kind() string {
|
|
return s.kind
|
|
}
|
|
|
|
func (s *simpleFactoryContext) ConfigureLogger(logger *zap.Logger) *zap.Logger {
|
|
return logger.Named(fmt.Sprintf("%s[%s]", s.Kind(), s.id))
|
|
}
|
|
|
|
func (s *simpleFactoryContext) Provide(constructors ...interface{}) {
|
|
s.AddOption(fx.Provide(constructors...))
|
|
}
|
|
|
|
func (s *simpleFactoryContext) Invoke(funcs ...interface{}) {
|
|
s.AddOption(fx.Invoke(funcs...))
|
|
}
|
|
|
|
func (s *simpleFactoryContext) Id() string {
|
|
return s.id
|
|
}
|
|
|
|
func (s *simpleFactoryContext) NameTag() string {
|
|
return fmt.Sprintf(`name:"%s"`, s.id)
|
|
}
|
|
|
|
func (s *simpleFactoryContext) GroupTag() string {
|
|
return fmt.Sprintf(`group:"%s"`, s.id)
|
|
}
|
|
|
|
func (s *simpleFactoryContext) ExtractConfig(destination any) error {
|
|
return mapstructure.Decode(s.config, destination)
|
|
}
|
|
|
|
func (s *simpleFactoryContext) AddOption(option fx.Option) {
|
|
s.options = append(s.options, option)
|
|
}
|
|
|
|
type simpleFactory = func(context ModuleFactoryContext) error
|
|
|
|
type simple struct {
|
|
name string
|
|
factory simpleFactory
|
|
}
|
|
|
|
func (s simple) Name() string {
|
|
return s.name
|
|
}
|
|
|
|
func (s simple) Create(id string, config map[string]interface{}) (fx.Option, error) {
|
|
ctx := &simpleFactoryContext{
|
|
options: make([]fx.Option, 0),
|
|
config: config,
|
|
id: id,
|
|
kind: s.name,
|
|
}
|
|
|
|
err := s.factory(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return fx.Options(ctx.options...), nil
|
|
}
|
|
|
|
func SimpleModule(name string, factory simpleFactory) Module {
|
|
module := &simple{name: name, factory: factory}
|
|
RegisterModule(module)
|
|
return module
|
|
}
|