addFactories($factoryMethods); } /** * @param string $name * * @return bool */ public function has($name) { return $this->hasService($name) || $this->hasFactory($name); } /** * @param string $name * * @throws ServiceNotFoundException * * @return object|mixed */ public function get($name) { if ($this->hasService($name)) { return $this->services[$name]; } if ($this->hasFactory($name)) { $definition = $this->factories[$name]; $factoryMethod = $definition->getCallable(); $serviceInstance = $factoryMethod($this->get('ServiceContainer')); //inject Logger if required if ( $this->has('Logger') && in_array(LoggerAwareTrait::class, class_uses($serviceInstance), true) ) { /** @var LoggerAwareTrait $serviceInstance */ $serviceInstance->setLogger($this->get('Logger')); } // Don't save non-shared services if (!$definition->isShared()) { return $serviceInstance; } // Save shared services $this->add($name, $serviceInstance); return $this->services[$name]; } throw new ServiceNotFoundException(sprintf( 'Service "%s" was not found.', $name )); } /** * @param string $name * @param object $instance * * @throws InvalidArgumentException */ public function add($name, $instance) { if (!is_object($instance)) { throw new InvalidArgumentException(sprintf( '%s could not be added. Only objects can be added to container.', $name )); } $this->services[$name] = $instance; } /** * @param string $name * * @return bool */ public function hasFactory($name) { return isset($this->factories[$name]); } /** * @param string $name * @param callable $callable * @param bool $shared * * @throws InvalidArgumentException */ public function addFactory($name, $callable, $shared = true) { if (!is_callable($callable, true)) { throw new InvalidArgumentException(sprintf( 'Factory "%s" can not be added. Second argument must be a callable.', $name )); } if (!is_string($name)) { throw new InvalidArgumentException(sprintf( 'Factory "%s" can not be added. Factory name must be a string.', $name )); } if ($this->hasFactory($name)) { throw new InvalidArgumentException(sprintf( 'Factory "%s" can not be added. Factory is already present.', $name )); } $this->factories[$name] = new FactoryMethodDefinition($callable, $shared); } /** * @param array|\Iterator $factories */ public function addFactories($factories) { foreach ($factories as $name => $callable) { $this->addFactory($name, $callable, true); } } /** * @param string $name * * @return bool */ private function hasService($name) { return isset($this->services[$name]); } }