*/ private array $factories = array(); /** * Resolved service instances, keyed by service id. * * @var array */ private array $resolved = array(); /** * Registers a service factory, resolved once and cached as a singleton. * * @param string $id Service identifier (usually a FQCN). * @param callable $factory Factory receiving the container and returning the service. * @return void */ public function set( string $id, callable $factory ): void { $this->factories[ $id ] = $factory; unset( $this->resolved[ $id ] ); } /** * Registers an already-constructed value as a singleton. * * @param string $id Service identifier. * @param mixed $value Concrete value. * @return void */ public function value( string $id, $value ): void { $this->resolved[ $id ] = $value; unset( $this->factories[ $id ] ); } /** * Resolves and returns a service. * * @param string $id Service identifier. * @return mixed * * @throws ServiceNotFoundException When the id is not registered. */ public function get( string $id ) { if ( array_key_exists( $id, $this->resolved ) ) { return $this->resolved[ $id ]; } if ( ! isset( $this->factories[ $id ] ) ) { throw new ServiceNotFoundException( esc_html( "Service [$id] is not registered." ) ); } $service = ( $this->factories[ $id ] )( $this ); $this->resolved[ $id ] = $service; return $service; } /** * Reports whether a service is registered. * * @param string $id Service identifier. * @return bool */ public function has( string $id ): bool { return isset( $this->factories[ $id ] ) || array_key_exists( $id, $this->resolved ); } }