registry.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package xpc
  2. import (
  3. "reflect"
  4. "sync"
  5. )
  6. // componentInfo holds metadata about a registered component.
  7. type componentInfo struct {
  8. Name string
  9. InterfaceType reflect.Type
  10. ImplType reflect.Type
  11. NewFunc func() any // Returns a pointer to the implementation
  12. }
  13. var (
  14. registryMu sync.RWMutex
  15. components = make(map[reflect.Type]*componentInfo)
  16. byName = make(map[string]*componentInfo)
  17. )
  18. // registerComponent registers a component implementation.
  19. // intfPtr: (*Interface)(nil)
  20. // implPtr: (*Implementation)(nil) or the implementation type instance
  21. // newFunc: function that returns a new instance of the implementation
  22. func registerComponent(intfPtr any, implPtr any, newFunc func() any) {
  23. registryMu.Lock()
  24. defer registryMu.Unlock()
  25. intfType := reflect.TypeOf(intfPtr).Elem()
  26. implType := reflect.TypeOf(implPtr)
  27. if implType.Kind() == reflect.Ptr {
  28. implType = implType.Elem()
  29. }
  30. info := &componentInfo{
  31. Name: intfType.PkgPath() + "." + intfType.Name(),
  32. InterfaceType: intfType,
  33. ImplType: implType,
  34. NewFunc: newFunc,
  35. }
  36. components[intfType] = info
  37. byName[info.Name] = info
  38. }
  39. // getComponentInfo returns the component info for the given interface type.
  40. func getComponentInfo(intfType reflect.Type) (*componentInfo, bool) {
  41. registryMu.RLock()
  42. defer registryMu.RUnlock()
  43. info, ok := components[intfType]
  44. return info, ok
  45. }