Eu só estava enfrentando isso. A postagem original é bem antiga, então as coisas podem ser diferentes agora do que quando foi postada, no entanto, o que descobri é que o construtor DI funciona, mas tem uma grande ressalva.
Se eu usar a seguinte característica no meu código:
<?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;
}
}
e prossiga para usar essa característica em uma classe:
<?php
namespace My\Module;
use \My\Module\Util\LoggerTrait;
class Service
{
use LoggerTrait;
public function doSomething() {
$this->getLogger()->log('Something was done!');
}
}
A interface do logger é injetada perfeitamente e tudo funciona bem. No entanto, se eu quiser injetar minhas próprias classes na minha classe Service usando o método construtor. Por exemplo:
<?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!');
}
}
Nesse caso, o método construtor da minha característica nunca é chamado, o que significa que a propriedade $ logger da minha classe nunca é definida. É certo que eu não usei muito os traços, por isso meu conhecimento é meio limitado, mas minha suposição é que isso ocorre porque minha classe substituiu o método construtor do meu traço. Isso é praticamente uma rolha de exibição, já que a maior parte da base de código Magento usa construtores para injetar dependências, descartando afetivamente seu uso em características.
A única solução real que posso ver é usar o ObjectManager diretamente para injetar suas dependências de características:
<?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;
}
}
Isenção de responsabilidade: O uso do ObjectManager no Magento geralmente é desencorajado, mas pelo que posso ver neste caso, é a única opção real. No meu exemplo, se você quiser definir uma interface de logger diferente em sua classe, ainda poderá fazê-lo injetando-a em seu construtor e substituindo a propriedade $ logger das classes.