zalas / injector
将 PSR-11 服务容器中的服务注入到对象中
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0
- psr/container: ^1.0 || ^2.0
Requires (Dev)
- phpspec/prophecy: ^1.9
- phpspec/prophecy-phpunit: ^2.2
- phpunit/phpunit: ^10.0 || ^11.0
README
从 PSR-11 依赖注入容器 中将服务注入到对象中。服务信息从带有 @inject
注解的类属性中读取,但也提供了从任何来源读取的扩展点。
默认实现可以与之工作的类的示例
class Foo { /** * @inject */ private Service1 $service1; /** * @inject foo.service2 */ private Service2 $service2; }
为什么?
当无法控制对象的实例化方式时,此库非常有用,因此无法使用适当的依赖注入。一个用例是将应用程序容器中的服务提供到集成测试用例。测试用例是由测试框架实例化的,因此无法在构建时提供额外的依赖项。然而,由于测试框架通常提供挂钩初始化过程的方法,因此仍然可以在调用测试用例之前提供额外的依赖项。
PHPUnit 集成实际上是在 zalas/phpunit-injector
中实现的(github 仓库:https://github.com/jakzal/phpunit-injector)。
安装
composer require zalas/injector
使用方法
属性需要使用 @inject
注解,以便默认注入器实现能够识别它们
class Foo { /** * @inject */ private Service1 $service1; /** * @inject foo.service2 */ private Service2 $service2; public function hasService1(): bool { return $this->service1 instanceof Service1; } public function hasService2(): bool { return $this->service2 instanceof Service2; } } class Service1 { } class Service2 { }
可以使用注入器将服务注入到已实例化的对象的属性中
use Zalas\Injector\Service\Injector; use Zalas\Injector\Factory\DefaultContainerFactory; use Zalas\Injector\Factory\DefaultExtractorFactory; $foo = new Foo(); $container = /* create / fetch your container */; $injector = new Injector(new DefaultContainerFactory($container), new DefaultExtractorFactory()); $injector->inject($foo); var_dump($foo->hasService1()); // bool(true) var_dump($foo->hasService2()); // bool(true)
扩展点
Zalas\Injector\Service\Injector
将服务注入到对象中。服务由 PSR-11 容器 (Psr\Container\ContainerInterface
) 提供。使用提取器 (Zalas\Injector\Service\Extractor
) 读取要注入的服务详细信息。
这两个协作者都通过它们的工厂 (Zalas\Injector\Service\ContainerFactory
和 Zalas\Injector\Service\ExtractorFactory
) 访问。
注入器提供两个扩展点
- 容器工厂 - 允许更改容器创建的方式
- 提取器 & 提取器工厂 - 允许提供一种自定义方式来提取要注入服务的定义
容器工厂
Zalas\Injector\Factory\DefaultContainerFactory
是一个默认的工厂实现,它始终返回外部创建的容器实例。
需要实现 Zalas\Injector\Service\ContainerFactory
接口,以提供用于与注入器一起使用的自定义服务容器创建方式。
提取器 & 提取器工厂
默认的提取器实现 (Zalas\Injector\Reflection\ReflectionExtractor
) 利用 PHP 的反射进行注解解析。它使用 @inject
注解来读取服务信息。注解接受服务 ID 作为可选值。否则,使用类型。 Zalas\Injector\Factory\DefaultExtractorFactory
创建此默认提取器实现。
实现 Zalas\Injector\Service\Extractor
接口以支持您自己的提取要注入服务的定义的方式。还需要创建一个实现 Zalas\Injector\Service\ExtractorFactory
的工厂来实例化自定义提取器。