diff --git a/phpstan.neon b/phpstan.neon index 672e0fa..d4e9fd3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 1 + level: 2 paths: - src \ No newline at end of file diff --git a/src/Container.php b/src/Container.php index 4857ccc..38850e6 100644 --- a/src/Container.php +++ b/src/Container.php @@ -4,11 +4,19 @@ namespace Danu\PhpDi; +use Danu\PhpDi\Contracts\ContainerContract; +use Danu\PhpDi\Exception\ContainerException; use ReflectionClass; +use ReflectionException; use ReflectionNamedType; -final class Container +class Container implements ContainerContract { + /** + * @var array + */ + private array $services = []; + /** * The container's instance. * @@ -27,13 +35,32 @@ final class Container public static function instance(): static { - if (is_null(static::$instance)) { - static::$instance = new static; + if (!isset(self::$instance)) { + self::$instance = new self(); } - return static::$instance; + return self::$instance; + } + + /** + * @param string $id + * @return object + */ + public function get(string $id): object + { + if(!isset($this->services[$id])) throw ContainerException::notFoundContainer($id); + + return $this->make($this->services[$id]); } + /** + * @param string $id + * @return bool + */ + public function has(string $id): bool + { + return isset($this->services[$id]); + } /** * @param $class @@ -42,10 +69,15 @@ public static function instance(): static */ public function make($class, array $parameters = []): mixed { - $classReflection = new ReflectionClass($class); + try { + $classReflection = new ReflectionClass($class); + } catch (ReflectionException $e) { + throw ContainerException::classDoesNotExist($class::class); + } + $constructorParams = $classReflection->getConstructor()->getParameters(); - $dependencies = $dependencies = $this->resolveParams($constructorParams, $parameters); + $dependencies = $this->resolveParams($constructorParams, $parameters); return $classReflection->newInstance(...$dependencies); } @@ -121,4 +153,8 @@ private function __construct() private function __clone(): void { } + + private function __wakeup() + { + } } diff --git a/src/Contracts/ContainerContract.php b/src/Contracts/ContainerContract.php index fbd63a8..e3f61d4 100644 --- a/src/Contracts/ContainerContract.php +++ b/src/Contracts/ContainerContract.php @@ -11,9 +11,6 @@ interface ContainerContract * * @param string $id Identifier of the entry to look for. * - * @throws NotFoundExceptionInterface No entry was found for **this** identifier. - * @throws ContainerExceptionInterface Error while retrieving the entry. - * * @return mixed Entry. */ public function get(string $id): mixed; @@ -21,10 +18,7 @@ public function get(string $id): mixed; /** * Returns true if the container can return an entry for the given identifier. * Returns false otherwise. - * - * `has($id)` returning true does not mean that `get($id)` will not throw an exception. - * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`. - * + ** * @param string $id Identifier of the entry to look for. * * @return bool diff --git a/src/Exception/ContainerException.php b/src/Exception/ContainerException.php index cb0fe06..95b6bcc 100644 --- a/src/Exception/ContainerException.php +++ b/src/Exception/ContainerException.php @@ -8,8 +8,13 @@ class ContainerException extends InternalException * @param string $id * @return static */ - public static function NotFoundContainer(string $id): static + public static function notFoundContainer(string $id): static { return self::make("No entry was found for **this** identifier: {$id}"); } + + public static function classDoesNotExist(string $className): static + { + return self::make("Class does not exist: {$className}"); + } } \ No newline at end of file