Вопрос

Когда я думаю, что у меня в голове была система DI из Magento 2, что-то приходит и разворачивает ее.
Я вижу в основном коде разные способы доступа к помощнику.
Например в Magento\Catalog\Controller\Category::_initCategory есть это:

if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
    return false;
}

Но в Magento\Catalog\Block\Category\View помощник внедряется в конструктор

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Model\Layer\Category $catalogLayer,
    \Magento\Framework\Registry $registry,
    \Magento\Catalog\Helper\Category $categoryHelper,
    array $data = array()
) {
    $this->_categoryHelper = $categoryHelper;
    $this->_catalogLayer = $catalogLayer;
    $this->_coreRegistry = $registry;
    parent::__construct($context, $data);
}

Это заставило меня подумать, что доступ к помощникам должен осуществляться по-разному в контроллерах и блоках (и моделях), но затем я нашел контроллер, в котором помощник вводится в конструктор. Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute.

Пожалуйста, рассейте для меня туман.
Когда мне следует использовать DI, а когда следует использовать objectManager?и почему?
Я прочитал этот вопрос: Создание экземпляров помощников в Magento 2.Это просто дополнительный вопрос по этому поводу.

Это было полезно?

Решение

Я бы предпочел Di, где это возможно, поскольку использование менеджера объекта уже является нарушением закона Деметатера.При использовании менеджера объекта эти зависимости просто скрыты в логике метода.

Другие советы

Я не так уж много знаю о реализации Magento, но похоже, что ObjectManager это Поиск сервисов.

Обычно использование локатора служб для доступа к зависимостям в объекте довольно плохо, проверьте Эта статья.

Гораздо лучший подход — явное определение ваших зависимостей через конструктор.Это помогает при модульном тестировании и решении проблем во время выполнения, когда службы не определены.

Внедрение диспетчера объектов в класс — это, по сути, внедрение в ваш класс реестра, который имеет доступ ко всем службам ваших приложений, что явно неправильно.

я использую ZF2 немного и обычно определяют небольшие фабричные классы для служб, контроллеров и любых классов, которые требуют зависимостей.Эти фабричные классы имеют доступ к локатору служб, захватывают все службы, от которых зависит объект, и внедряют их через конструктор.Использование локатора службы в классе Factory вполне допустимо, поскольку в основном это ненужный код, что-то вроде этот например.

Эти фабрики по-прежнему легко тест.

ИМО, используйте внедрение конструктора везде, где это возможно.Опять же, я не слишком много знаю о реализации Magento, и если в нем есть концепция фабрик, то при беглом взгляде кажется, что он их поддерживает, но явное определение ваших классов и использование локатора сервисов для их создания в классах фабрики - это гораздо более чистый подход.

Это от человека, который мало знаком с вышеупомянутыми шаблонами, поэтому я также хотел бы услышать мысли/опыт других по этому поводу!

Больше чтения

Еще один способ использовать помощник (в шаблонах):

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]')->getMethodName();
.

Я надеюсь, что это полезно, если вы уже не знаете.

Хотя это старый вопрос, я не уверен, Мариус получил свой ответ.Я считаю Мариус можешь ответить лучше.Я хотел бы ответить на него вкратце.Почему Magento 2 предлагает использовать DI вместо помощника?

  • Сделать изоляцию в модульном тестировании возможной/простой
  • Явное определение зависимостей класса
  • Содействие хорошему дизайну (например, принцип единой ответственности (SRP))
  • Использование DI в вашем модуле снижает риск ошибок несовместимости, когда Magento меняет основную реализацию этих интерфейсов.Это важная концепция, которую следует понимать разработчикам расширений.

Почему ядро ​​M2 может не использовать DI в некоторых случаях?

  • Уменьшение количества классов
  • Отсутствие создания ненужных интерфейсов
  • Нет риска ошибок несовместимости

Хотя основной модуль каталога использовался в качестве вспомогательного средства, он широко использовал DI.В ходе своего исследования я обнаружил, что Magento 2 использует несколько функций во вспомогательных файлах основного каталога, которые не подходят для сервисных контрактов.

Если вам необходимо явно использовать класс, определенный Magento (например, \Magento\Catalog\Model\Product), сделайте неявную зависимость явной, в зависимости от конкретной реализации, а не от интерфейса контракта службы.

Несомненно, разработчик расширений должен использовать DI вместо Magento1, как Helper.При реализации в соответствии с рекомендациями Magento 2 последствия ограничены.При нарушении рекомендаций случаются проблемы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top