Я просто столкнулся с этим сам. Исходное сообщение довольно старое, так что теперь все может отличаться от того, когда оно было опубликовано, однако я обнаружил, что конструктор DI работает, но у него довольно большое предостережение.
Если я использую следующую черту в моем коде:
<?php
namespace My\Module\Util;
use Psr\Log\LoggerInterface;
trait LoggerTrait
{
protected $logger;
public function __construct(
LoggerInterface $logger
) {
$this->logger = $logger;
}
/**
* @return Logger
*/
public function getLogger()
{
return $this->logger;
}
/**
* @param Logger $logger
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
}
а затем перейдите к использованию этой черты в классе:
<?php
namespace My\Module;
use \My\Module\Util\LoggerTrait;
class Service
{
use LoggerTrait;
public function doSomething() {
$this->getLogger()->log('Something was done!');
}
}
Интерфейс логгера вводится отлично и все работает отлично. ОДНАКО, если я хочу внедрить свои собственные классы в мой класс Service, используя метод конструктора. Например:
<?php
namespace My\Module;
use \My\Module\Util\LoggerTrait;
class Service
{
use LoggerTrait;
public function __construct(
\Some\Other\Class $class
) {
$this->other = $class;
}
public function doSomething() {
$this->getLogger()->log('Something was done!');
}
}
В этом случае метод конструктора моей черты никогда не вызывается, то есть свойство $ logger моего класса никогда не устанавливается. По общему признанию, я не использовал черты, поэтому мои знания ограничены, но я предполагаю, что это потому, что мой класс переопределил метод конструктора моей черты. Это в значительной степени ограничитель показа, так как большая часть кода Magento использует конструкторы для введения зависимостей, аффективно исключая их использование в чертах.
Единственное реальное решение, которое я вижу, - это использовать ObjectManager напрямую, чтобы ввести зависимости от вас:
<?php
namespace My\Module\Util;
use Psr\Log\LoggerInterface;
trait LoggerTrait
{
protected $logger;
/**
* @return Logger
*/
public function getLogger()
{
if (is_null($this->logger)) {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->logger = $objectManager->create('Psr\Log\LoggerInterface');
}
return $this->logger;
}
/**
* @param Logger $logger
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
}
Отказ от ответственности: использование ObjectManager в Magento, как правило, не рекомендуется, но из того, что я вижу в этом случае, это единственный реальный вариант. В моем примере, если вы хотите установить другой интерфейс логгера в своем классе, вы все равно можете сделать это, внедрив его в конструктор и переопределив свойство классов $ logger.