Kiedy myślę, że owinąłem głowę wokół systemu DI z Magento 2, coś pojawia się i rozpakowuje.
Widzę w kodzie podstawowym różne sposoby dostępu do pomocnika.
Na przykład Magento\Catalog\Controller\Category::_initCategory
jest tam:
if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
return false;
}
Ale w Magento\Catalog\Block\Category\View
pomocnika wstrzykuje się konstruktor
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);
}
Doprowadziło mnie to do wniosku, że pomoce powinny być dostępne w różny sposób w kontrolerach i blokach (i modelach), ale potem znalazłem kontroler, w którym pomocnik jest wstrzykiwany do konstruktora Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute
.
Proszę, wyczyść dla mnie mgłę.
Kiedy powinienem używać DI, a kiedy powinienem objectManager
? i dlaczego?
Przeczytałem to pytanie: Tworzenie instancji Pomocników w Magento 2 . To tylko kolejne pytanie na ten temat.
źródło
Nie wiem dużo o implementacji Magento, ale wygląda na
ObjectManager
to, że jest lokalizatorem usług .Zasadniczo używanie Lokalizatora usług do uzyskiwania dostępu do zależności w obiekcie jest dość złe, sprawdź ten artykuł .
Definiowanie własnych zależności za pomocą konstruktora jest znacznie lepszym podejściem. Pomaga w testowaniu jednostkowym i problemach z czasem działania, gdy usługi nie są zdefiniowane.
Wstrzyknięcie Menedżera obiektów do klasy jest po prostu wstrzyknięciem Rejestru do klasy, która ma dostęp do wszystkich usług aplikacji, co oczywiście nie jest właściwe.
Używam ZF2 dość często i ogólnie definiuję małe klasy fabryczne dla usług, kontrolerów i każdej klasy wymagającej zależności. Te klasy fabryczne mają dostęp do Lokalizatora usług i pobierają wszystkie usługi, od których zależy obiekt, i wstrzykują je przez konstruktor. Korzystanie z usługi lokalizatora w klasie Fabryka jest w porządku, jak to jest w większości wyrzucić kod, coś jak to na przykład.
Te fabryki są nadal łatwe do przetestowania .
IMO, Użyj iniekcji konstruktora tam, gdzie to możliwe. Znowu nie wiem zbyt wiele o implementacji Magento i jeśli ma ona koncepcję Fabryki, to od razu wygląda na to, że je obsługuje, ale wyraźne zdefiniowanie klas i użycie Lokalizatora usług do zbudowania ich w klasach Fabryki to znacznie czystsze podejście.
To jest od kogoś, kto ma ograniczone kontakt z wyżej wymienionymi wzorami, dlatego też chciałbym usłyszeć czyjeś myśli / doświadczenia w tej sprawie!
Więcej lektur
źródło
Innym sposobem korzystania z pomocnika (w szablonach) jest:
Mam nadzieję, że jest to przydatne, jeśli jeszcze tego nie wiesz.
źródło
Choć to stare pytanie, nie jestem pewien, czy Marius otrzymał odpowiedź. Wierzę, że Marius może lepiej odpowiedzieć. Chciałbym krótko odpowiedzieć na to pytanie. Dlaczego Magento 2 sugeruje użycie DI zamiast pomocnika?
Dlaczego w niektórych przypadkach rdzeń M2 może nie używać DI?
Chociaż moduł katalogowy Core został użyty jako pomocnik, to w znacznym stopniu wykorzystał DI. W moich badaniach odkryłem, że Magento 2 używało kilku funkcji w plikach pomocniczych katalogu głównego, które nie są odpowiednie dla umów serwisowych.
Jeśli musisz jawnie użyć klasy zdefiniowanej przez Magento (takiej jak \ Magento \ Catalog \ Model \ Product), wyraź jawną zależność domyślną, zależnie od konkretnej implementacji zamiast interfejsu umowy serwisowej.
Niewątpliwie deweloper rozszerzeń powinien używać DI zamiast Magento1 jak Helper. Podczas wdrażania zgodnie z wytycznymi Magento 2 opadanie jest ograniczone. Podczas łamania zaleceń zdarzają się problemy.
źródło