package sdk import ( "fmt" "strings" "sync" ) type Reference struct { Category Category Type string } type Registration interface { RegisterAt(registry *TypeRegistry) } type RegistrationFunc func(registry *TypeRegistry) func (f RegistrationFunc) RegisterAt(registry *TypeRegistry) { f(registry) } func NewTypeRegistry() *TypeRegistry { return &TypeRegistry{ registrations: make(map[string]Factory), } } type TypeRegistry struct { lock sync.Mutex registrations map[string]Factory } func (r *TypeRegistry) List() (refs []Reference) { refs = make([]Reference, 0, len(r.registrations)) for k := range r.registrations { split := strings.SplitN(k, "/", 2) if len(split) < 2 { continue } refs = append(refs, Reference{ Category: Category(split[0]), Type: split[1], }) } return refs } func (r *TypeRegistry) Add(cat Category, moduleName string, factory Factory) { r.lock.Lock() defer r.lock.Unlock() r.registrations[specOf(cat, moduleName)] = factory } func (r *TypeRegistry) Get(cat Category, moduleName string) Module { f, ok := r.registrations[specOf(cat, moduleName)] if !ok { return nil } return f.Create() } func specOf(cat Category, moduleName string) string { return fmt.Sprintf("%s/%s", cat.String(), moduleName) }