J'étais juste face à ça moi-même. Le message d'origine est assez ancien, donc les choses peuvent être différentes maintenant que lorsqu'il a été publié, mais ce que j'ai trouvé, c'est que le constructeur DI fonctionne, mais il a une mise en garde assez importante.
Si j'utilise le trait suivant dans mon code:
<?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;
}
}
puis continuez à utiliser ce trait dans une classe:
<?php
namespace My\Module;
use \My\Module\Util\LoggerTrait;
class Service
{
use LoggerTrait;
public function doSomething() {
$this->getLogger()->log('Something was done!');
}
}
L'interface de l'enregistreur est parfaitement injectée et tout fonctionne bien. CEPENDANT, si je veux injecter mes propres classes dans ma classe Service en utilisant la méthode constructeur. Par exemple:
<?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!');
}
}
Dans ce cas, la méthode constructeur de ma caractéristique n'est jamais appelée, ce qui signifie que la propriété $ logger de ma classe n'est jamais définie. Certes, je n'ai pas beaucoup utilisé les traits, donc mes connaissances sont assez limitées, mais je suppose que c'est parce que ma classe a outrepassé la méthode constructeur de mon trait. C'est à peu près un bouchon de show car la plupart de la base de code Magento utilise des constructeurs pour injecter des dépendances, excluant affectivement leur utilisation dans les traits.
La seule vraie solution que je puisse voir est d'utiliser directement l'ObjectManager pour injecter vos dépendances de traits:
<?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;
}
}
Avertissement: L'utilisation d'ObjectManager dans Magento est généralement déconseillée mais d'après ce que je peux voir dans ce cas, c'est la seule véritable option. Dans mon exemple, si vous souhaitez définir une autre interface de journalisation dans votre classe, vous pouvez toujours le faire en l'injectant dans votre constructeur et en remplaçant la propriété classes $ logger.