PHP-DI InjectOn 未注入 setter 方法

问题描述 投票:0回答:2

我在使用

ContainerBuilder
配置容器时设置了依赖项和定义,然后编译它以获得实际的
Container
,但每当我尝试注入依赖项时,它们总是会被忽略。

我是否错过了

injectOn()
方法的概念,或者我在这里做错了什么(
$this->translator
仍未分配)?我尝试了不同的方法,既实例化类并将对象添加到
ContainerBuilder
中,又将其作为
\DI\object()
定义传递,两者都具有相同的结果。

<?php
include "../vendor/autoload.php";

class Translator
{}

class TextHandle
{
    protected $translator;

    public function setTranslator (Translator $translator)
    {
        $this->translator = $translator;
    }

    public function test ()
    {
        var_dump($this->translator);
    }
}

class TestCase
{
    protected $translator;

    public function __construct (Translator $translator)
    {
        $this->translator = $translator;
    }
}

// Setup container
$containerBuilder = new \DI\ContainerBuilder();
$containerBuilder->addDefinitions([
    Translator::class => \DI\object(),
]);

$container = $containerBuilder->build();

// Create object and inject
$textHandle = new TextHandle();
$container->injectOn($textHandle);

// Test injection, fails
$textHandle->test(); // NULL

// Test access, works
$translator = $container->get(Translator::class);
var_dump($translator); // object(Translator)#18 (0) {}

// Try having the container instantiate
$textHandle = $container->make(TextHandle::class);
$textHandle->test(); // Null

// Try object with constructor, works
$testCase = $container->make(TestCase::class);
var_dump($testCase); // Translator is set
php dependency-injection inversion-of-control php-di
2个回答
4
投票

根据文档,PHP-DI 不通过setter 执行自动装配。

您应该添加

TextHandle
类的定义,并将其配置为通过 setter 注入
Translator

$containerBuilder->addDefinitions([
    TextHandle::class => \DI\object()->method('setTranslator', \DI\get(Translator::class))
]);

0
投票

如果您使用 PHP 7.4、PHP DI 6.x

事实上,您可以使用属性注入或 Setter 注入来注入依赖项

$container->injectOn($object)

这是详细信息。

  1. 构建容器时添加此行:
    $builder->useAnnotation(true)
  2. 将学说/注释 v 1.x 添加到您的依赖项中:
    composer require doctrine/annotations:^1.14
  3. 在您的类中,在属性或 setter 方法之前添加此注释:
/**
 * @Inject
 */
private NotificationServicesInterface $notificationServices;

与/或

private NotificationServicesInterface $notificationServices;

/**
 * @Inject
 */
public function setNotificationServices(NotificationServicesInterface $notificationServices) {
    $this->notificationServices = $notificationServices;
}

注:

  • 根据文档,https://php-di.org/doc/container.html#injecton,默认情况下您应该使用
    make()
    call()
    。仅在必要时才使用
    injectOn()
  • 对于 PHP 8 或更高版本,您将使用 PHP DI 7,并且您将使用 PHP 8 的属性:
#[Inject]
private NotificationServicesInterface $notificationServices;
  • 我还没有尝试过 PHP 8,但也许你不再需要学说/注释了
© www.soinside.com 2019 - 2024. All rights reserved.