2016-11-25 6 views
4

У меня есть настройки зависимостей и определений при конфигурировании контейнера с использованием ContainerBuilder, а затем скомпилировать его для получения фактического Container, но всякий раз, когда я пытаюсь впрыскивать зависимости, они всегда игнорируются.PHP-DI injectOn не инъецирует на методы setter

Я пропустил концепцию метода 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 

ответ

3

Согласно the documentation, PHP-DI не выполняет автоматическое связывания через сеттер.

Вы должны добавить определение для TextHandle класса и настроить его, чтобы придать Translator через сеттер:

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

Руководство раздела вы связаны относится к сценарию, когда контейнер экземпляра объекта без типа намекали аргументы конструктора. Мой объект не имеет конструктора и создается вручную. Он все еще применяется? ** Редактировать: ** http://php-di.org/doc/inject-on-instance.html В этом разделе руководства говорится: «Теперь объект $ имеет все свои зависимости, введенные (через инъекции сеттера и вложения свойств) .' – Daniel

+0

Ключевым моментом здесь является «' setLogger() 'не будет вызываться». Это заставляет меня предположить, что аутсорсинг не работает с сеттерами, но только с конструкторами. Плохая практика заключается в том, чтобы вручную создавать классы, в которых должны быть введены зависимости. Вы должны получить экземпляр TextHandle из контейнера. –

+0

Чтобы ответить на ваше редактирование: я думаю, что в этом случае вы должны иметь правильную конфигурацию инъекций в контейнере. Попробуйте добавить определение так, как я описал его, прежде чем вызывать 'injectOn()'. Кроме того, предложение «в некоторых ситуациях, у вас нет контроля над созданием объекта», очень озадачивает меня, я понятия не имею, как это возможно. –