Files
summercms/modules/backpack/services.go
Jakub Zych 5e50b166ef refactor(10.2-01): nest framework packages under modules
- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
2026-09-28 02:21:02 +02:00

61 lines
1.2 KiB
Go

package backpack
import (
"fmt"
"reflect"
"sync"
)
// Registry is an app-scoped typed service catalog. It has no process-global state.
type Registry struct {
mu sync.RWMutex
m map[reflect.Type]any
}
// NewRegistry returns an empty service registry.
func NewRegistry() *Registry {
return &Registry{m: make(map[reflect.Type]any)}
}
// Publish stores value under the concrete type argument T. Publishing the
// same T twice is an error.
func (r *Registry) Publish[T any](value T) error {
if r == nil {
return fmt.Errorf("backpack: registry is nil")
}
if any(value) == nil {
return fmt.Errorf("backpack: publish nil service")
}
key := reflect.TypeFor[T]()
r.mu.Lock()
defer r.mu.Unlock()
if r.m == nil {
r.m = make(map[reflect.Type]any)
}
if _, exists := r.m[key]; exists {
return fmt.Errorf("backpack: duplicate provider for %s", key)
}
r.m[key] = value
return nil
}
// Lookup returns the service published under T, or (zero, false).
func (r *Registry) Lookup[T any]() (T, bool) {
var zero T
if r == nil {
return zero, false
}
key := reflect.TypeFor[T]()
r.mu.RLock()
defer r.mu.RUnlock()
v, ok := r.m[key]
if !ok {
return zero, false
}
got, ok := v.(T)
if !ok {
return zero, false
}
return got, true
}