Tôi chỉ phải đối mặt với điều này bản thân mình. Bài viết ban đầu khá cũ nên bây giờ mọi thứ có thể khác so với khi nó được đăng, tuy nhiên điều tôi thấy là hàm tạo DI hoạt động nhưng nó có một cảnh báo khá lớn.
Nếu tôi sử dụng Trait sau trong mã của mình:
<?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;
}
}
và sau đó tiến hành sử dụng đặc điểm đó trong một lớp:
<?php
namespace My\Module;
use \My\Module\Util\LoggerTrait;
class Service
{
use LoggerTrait;
public function doSomething() {
$this->getLogger()->log('Something was done!');
}
}
Giao diện logger được tiêm hoàn hảo và mọi thứ hoạt động tốt. TUY NHIÊN, nếu tôi muốn đưa các lớp của riêng mình vào lớp Dịch vụ của mình bằng phương thức constructor. Ví dụ:
<?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!');
}
}
Trong trường hợp này, phương thức constructor của đặc điểm của tôi không bao giờ được gọi, có nghĩa là thuộc tính $ logger của lớp tôi không bao giờ được đặt. Phải thừa nhận rằng tôi đã không sử dụng các đặc điểm nhiều nên kiến thức của tôi bị hạn chế, nhưng giả định của tôi là điều này là do lớp học của tôi đã ghi đè lên phương thức xây dựng của đặc điểm của tôi. Đây gần như là một điểm dừng hiển thị vì hầu hết các cơ sở mã Magento sử dụng các hàm tạo để tiêm phụ thuộc, ảnh hưởng đến việc loại bỏ việc sử dụng chúng trong các đặc điểm.
Giải pháp thực sự duy nhất tôi có thể thấy là sử dụng ObjectManager trực tiếp để tiêm phụ thuộc vào đặc điểm của bạn:
<?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;
}
}
Tuyên bố miễn trừ trách nhiệm: Việc sử dụng ObjectManager trong Magento thường không được khuyến khích nhưng từ những gì tôi có thể thấy trong trường hợp này là lựa chọn thực sự duy nhất. Trong ví dụ của tôi nếu bạn muốn thiết lập một giao diện logger khác trong lớp của mình, bạn vẫn có thể làm điều đó bằng cách đưa nó vào hàm tạo của bạn và ghi đè lên thuộc tính $ logger.