*/ private array $factories = array(); /** * Ids that should be resolved as singletons. * * @var array */ private array $shared = array(); /** * Resolved singleton instances. * * @var array */ private array $instances = array(); /** * Register a shared (singleton) service. * * @param string $id Service identifier. * @param callable $factory Factory receiving the container. */ public function singleton( string $id, callable $factory ): void { $this->factories[ $id ] = $factory; $this->shared[ $id ] = true; } /** * Register a factory that produces a fresh instance each time. * * @param string $id Service identifier. * @param callable $factory Factory receiving the container. */ public function bind( string $id, callable $factory ): void { $this->factories[ $id ] = $factory; $this->shared[ $id ] = false; } /** * Determine whether a service is registered. * * @param string $id Service identifier. */ public function has( string $id ): bool { return isset( $this->factories[ $id ] ); } /** * Resolve a service. * * @param string $id Service identifier. * @return mixed * @throws \RuntimeException When the service is not registered. */ public function get( string $id ) { if ( isset( $this->instances[ $id ] ) ) { return $this->instances[ $id ]; } if ( ! isset( $this->factories[ $id ] ) ) { throw new \RuntimeException( sprintf( 'Service "%s" is not registered in the container.', esc_html( $id ) ) ); } $object = ( $this->factories[ $id ] )( $this ); if ( ! empty( $this->shared[ $id ] ) ) { $this->instances[ $id ] = $object; } return $object; } }