loaderClassNames = $loaderClassNames; $this->configuration = $this->get('injectableFactory')->create($configurationClassName); } /** * Obtain a service object. */ public function get(string $name) : ?object { if (empty($this->data[$name])) { $this->load($name); } if (isset($this->data[$name])) { return $this->data[$name]; } return null; } /** * Check whether a service can be obtained. */ public function has(string $name) : bool { if (isset($this->data[$name])) 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)) { $obj = $this->$loadMethodName(); $this->data[$name] = $obj; return; } $loaderClassName = $this->loaderClassNames[$name] ?? $this->configuration->getLoaderClassName($name); $object = null; if ($loaderClassName) { $loadClass = $this->get('injectableFactory')->create($loaderClassName); $object = $loadClass->load(); $this->data[$name] = $object; } else { $className = $this->configuration->getServiceClassName($name); if ($className && class_exists($className)) { $dependencyList = $this->configuration->getServiceDependencyList($name); if (!is_null($dependencyList)) { $dependencyObjectList = []; foreach ($dependencyList as $item) { $dependencyObjectList[] = $this->get($item); } $reflector = new \ReflectionClass($className); $object = $reflector->newInstanceArgs($dependencyObjectList); } else { $object = $this->get('injectableFactory')->create($className); } $this->data[$name] = $object; } } } protected function loadContainer() { return $this; } protected function loadInjectableFactory() { return new InjectableFactory($this); } }