package xpc import ( "reflect" "sync" ) // componentInfo holds metadata about a registered component. type componentInfo struct { Name string InterfaceType reflect.Type ImplType reflect.Type NewFunc func() any // Returns a pointer to the implementation } var ( registryMu sync.RWMutex components = make(map[reflect.Type]*componentInfo) byName = make(map[string]*componentInfo) ) // registerComponent registers a component implementation. // intfPtr: (*Interface)(nil) // implPtr: (*Implementation)(nil) or the implementation type instance // newFunc: function that returns a new instance of the implementation func registerComponent(intfPtr any, implPtr any, newFunc func() any) { registryMu.Lock() defer registryMu.Unlock() intfType := reflect.TypeOf(intfPtr).Elem() implType := reflect.TypeOf(implPtr) if implType.Kind() == reflect.Ptr { implType = implType.Elem() } info := &componentInfo{ Name: intfType.PkgPath() + "." + intfType.Name(), InterfaceType: intfType, ImplType: implType, NewFunc: newFunc, } components[intfType] = info byName[info.Name] = info } // getComponentInfo returns the component info for the given interface type. func getComponentInfo(intfType reflect.Type) (*componentInfo, bool) { registryMu.RLock() defer registryMu.RUnlock() info, ok := components[intfType] return info, ok }