loaderClassNames = $loaderClassNames; $this->injectableFactory = $this->get('injectableFactory'); $this->configuration = $this->injectableFactory->create($configurationClassName); } /** * Obtain a service object. */ public function get(string $name) : object { if (!isset($this->data[$name])) { $this->load($name); if (!isset($this->data[$name])) { throw new Error("Could not load '{$name}' service."); } } return $this->data[$name]; } /** * Check whether a service can be obtained. */ public function has(string $name) : bool { if (isset($this->data[$name])) { return true; } if (array_key_exists($name, $this->loaderClassNames)) { return true; } $loadMethodName = 'load' . ucfirst($name); if (method_exists($this, $loadMethodName)) { return true; } if ($this->configuration->getLoaderClassName($name)) { return true; } if ($this->configuration->getServiceClassName($name)) { return true; } return false; } /** * Set a service object. Must be configured as settable. */ public function set(string $name, object $object) { if (!$this->configuration->isSettable($name)) { throw new Error("Service '{$name}' is not settable."); } $this->setForced($name, $object); } protected function setForced(string $name, object $object) { $this->data[$name] = $object; } private function load(string $name) { $loadMethodName = 'load' . ucfirst($name); if (method_exists($this, $loadMethodName)) { $this->data[$name] = $this->$loadMethodName(); return; } $loaderClassName = $this->loaderClassNames[$name] ?? $this->configuration->getLoaderClassName($name); if ($loaderClassName) { $loadClass = $this->injectableFactory->create($loaderClassName); $this->data[$name] = $loadClass->load(); return; } $className = $this->configuration->getServiceClassName($name); if (!$className || !class_exists($className)) { throw new Error("Could not load '{$name}' service."); } $dependencyList = $this->configuration->getServiceDependencyList($name); if (!is_null($dependencyList)) { $dependencyObjectList = []; foreach ($dependencyList as $item) { $dependencyObjectList[] = $this->get($item); } $reflector = new ReflectionClass($className); $this->data[$name] = $reflector->newInstanceArgs($dependencyObjectList); return; } $this->data[$name] = $this->injectableFactory->create($className); } protected function loadContainer() { return $this; } protected function loadInjectableFactory() { return new InjectableFactory($this); } }