zalas/injector

将 PSR-11 服务容器中的服务注入到对象中

支持包维护!
jakzal

v2.6.1 2024-06-04 10:37 UTC

README

Build

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\ContainerFactoryZalas\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 的工厂来实例化自定义提取器。

贡献

请阅读贡献指南以了解如何为该项目做出贡献。请注意,本项目遵循贡献者行为准则。参与本项目即表示您同意遵守其条款。