assodepicche / php-di-container
PHP 依赖注入容器
Requires
- php: >=8.2
Requires (Dev)
- phpunit/phpunit: ^10.2
This package is auto-updated.
Last update: 2024-09-30 01:57:35 UTC
README
根据 DotNetTricks,DI 容器是一个创建依赖项并在需要时自动注入它们的框架。它根据请求自动创建对象并在需要时注入它们。DI 容器以简单和便捷的方式帮助我们管理应用程序中的依赖项。
DI 容器创建定义的类的对象,并将所有必需的依赖项作为对象注入,包括构造函数、属性或方法,这些方法在运行时触发并在适当的时间销毁自己。这个过程完成,这样我们就不必总是手动创建和管理对象。
此存储库包含用于 PHP 项目的 DI 容器。
目录
接口
DependencyInjectionContainer
接口定义了四个方法:autowire
、get
、set
和 singleton
。所有这些方法都期望一个类或接口名称作为字符串,但只有后两个方法还期望一个 callable
,它代表类或接口的定义。
<?php declare(strict_types=1); namespace Container\Adapter; interface DependencyInjectionContainer { public function autowire(string $className): object; /** * @template TClassName * @param class-string<TClassName> $className * @return TClassName */ public function get(string $className): object; public function has(string $className): bool; public function set(string $className, callable $definition): self; public function singleton(string $className, callable $definition): self; }
实现
"DependencyInjectionContainer" 接口的实现是 "DependencyContainer" 类,并使用 PHP 反射 API 来管理已注册类的实例化。
<?php declare(strict_types=1); namespace Container\Infrastructure; use Container\Adapter\DependencyInjectionContainer; use ReflectionClass; use ReflectionParameter; final class DependencyContainer implements DependencyInjectionContainer { private array $definitions = []; private array $singletons = []; public function autowire(string $className): object { $reflectionClass = new ReflectionClass($className); $constructorParameters = array_map( fn (ReflectionParameter $parameter) => $this->get($parameter->getType()->getName()), $reflectionClass->getConstructor()?->getParameters() ?? [] ); return new $className(...$constructorParameters); } public function get(string $className): object { if ($instance = $this->singletons[$className] ?? null) { return $instance; } $definition = $this->definitions[$className] ?? $this->autowire(...); return $definition($className); } public function has(string $className): bool { return isset($this->definitions[$className]) || isset($this->singletons[$className]); } public function set(string $className, callable $definition): self { $this->definitions[$className] = $definition; return $this; } public function singleton(string $className, callable $definition): self { $this->definitions[$className] = function () use ($className, $definition) { $this->singletons[$className] = $definition($this); return $this->singletons[$className]; }; return $this; } }
安装
首先,请确保您已安装 PHP(8.2 版本或更高版本),然后克隆此存储库或通过 composer 安装库。
- 通过 Git 安装
git clone git@github.com:AssoDePicche/php-di-container.git
- 通过 Composer 安装
composer require assodepicche/php-di-container
入门
实例化 DependencyContainer
类
<?php use Container\Infrastructure\DependencyContainer; $container = new DependencyContainer;
使用 set
方法设置类的定义
$container->set(Foo::class, fn () => new Foo);
每次需要时都使用 get
方法调用定义的类
$object = $container->get(Foo::class);
使用 has
方法找出容器中是否已定义了接口
var_dump($container->has(Foo::class)); // true
注意:要将类设置为单例,请使用 singleton 方法
$container->singleton(Singleton::class, fn () => new SingletonClass);
贡献
要为此项目做出贡献,请按照以下步骤操作:遵循这些步骤。
联系
Samuel do Prado Rodrigues (AssoDePicche) - samuelprado730@gmail.com