Ich habe mich nur selbst damit konfrontiert. Der ursprüngliche Beitrag ist ziemlich alt, daher können die Dinge jetzt anders sein als zu dem Zeitpunkt, als er veröffentlicht wurde. Ich habe jedoch festgestellt, dass der Konstruktor DI zwar funktioniert, aber eine ziemlich große Einschränkung aufweist.
Wenn ich das folgende Merkmal in meinem Code verwende:
<?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;
}
}
und fahren Sie dann fort, dieses Merkmal in einer Klasse zu verwenden:
<?php
namespace My\Module;
use \My\Module\Util\LoggerTrait;
class Service
{
use LoggerTrait;
public function doSomething() {
$this->getLogger()->log('Something was done!');
}
}
Die Logger-Schnittstelle ist perfekt injiziert und alles funktioniert einwandfrei. JEDOCH, wenn ich meine eigenen Klassen mit der Konstruktormethode in meine Service-Klasse einfügen möchte. Z.B:
<?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!');
}
}
In diesem Fall wird die Konstruktormethode meines Merkmals niemals aufgerufen, was bedeutet, dass die Eigenschaft $ logger meiner Klasse niemals festgelegt wird. Zugegeben, ich habe nicht viel Merkmale verwendet, so dass mein Wissen etwas begrenzt ist, aber ich gehe davon aus, dass dies daran liegt, dass meine Klasse die Konstruktormethode meines Merkmals überschrieben hat. Dies ist so ziemlich ein Show-Stopper, da der Großteil der Magento-Codebasis Konstruktoren verwendet, um Abhängigkeiten zu injizieren, wodurch deren Verwendung in Merkmalen effektiv ausgeschlossen wird.
Die einzige wirkliche Lösung, die ich dafür sehen kann, besteht darin, den ObjectManager direkt zu verwenden, um Ihre Merkmalsabhängigkeiten zu injizieren:
<?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;
}
}
Haftungsausschluss: Von der Verwendung von ObjectManager in Magento wird im Allgemeinen abgeraten, aber soweit ich in diesem Fall sehen kann, ist dies die einzige echte Option. Wenn Sie in meinem Beispiel eine andere Logger-Schnittstelle in Ihrer Klasse festlegen möchten, können Sie dies dennoch tun, indem Sie sie in Ihren Konstruktor einfügen und die Eigenschaft class $ logger überschreiben.