di/di.go

94 lines
2.0 KiB
Go
Raw Normal View History

2022-07-17 02:51:22 +03:00
package di
import (
"fmt"
"sync"
)
var ( // singletones
services sync.Map
cache sync.Map
)
func init() {
services = sync.Map{}
cache = sync.Map{}
}
2022-07-26 04:56:30 +03:00
// Register service in di
func Register[T any](id string, constructor func() (*T, error)) {
services.Store(id, constructor)
}
2022-07-17 02:51:22 +03:00
// Get services by type
2022-07-26 04:56:30 +03:00
func GetByType[T any]() ([]*T, error) {
2022-07-17 02:51:22 +03:00
var err error
result := []*T{}
services.Range(func(id, constructor any) bool {
if constructor, ok := constructor.(func() (*T, error)); ok {
if instance, ok := cache.Load(id); ok {
if instance, ok := instance.(*T); ok {
result = append(result, instance)
}
return true
}
instance, instErr := constructor()
if instErr != nil {
err = instErr
return false
}
cache.Store(id, instance)
result = append(result, instance)
}
return true
})
return result, err
}
2022-07-26 04:56:30 +03:00
// Get services by interface
func GetByInterface[Interface any]() ([]Interface, error) {
var err error
result := []Interface{}
services.Range(func(id, constructor any) bool {
if constructor, ok := constructor.(func() (Interface, error)); ok {
if instance, ok := cache.Load(id); ok {
if instance, ok := instance.(Interface); ok {
result = append(result, instance)
}
return true
}
instance, instErr := constructor()
if instErr != nil {
err = instErr
return false
}
cache.Store(id, instance)
result = append(result, instance)
}
return true
})
return result, err
}
// Get service by id and type
func Get[T any](id string) (*T, error) {
2022-07-17 02:51:22 +03:00
if instance, ok := cache.Load(id); ok {
if instance, ok := instance.(*T); ok {
return instance, nil
}
2022-07-26 04:56:30 +03:00
return nil, fmt.Errorf("invalid type for service %s (%t)", id, instance)
2022-07-17 02:51:22 +03:00
}
if constructor, ok := services.Load(id); ok {
if constructor, ok := constructor.(func() (*T, error)); ok {
instance, err := constructor()
if err != nil {
return nil, err
}
cache.Store(id, instance)
return instance, nil
}
2022-07-26 04:56:30 +03:00
return nil, fmt.Errorf("invalid constructor")
2022-07-17 02:51:22 +03:00
}
return nil, fmt.Errorf("unknown service %s", id)
}