Magento 2: Object Manager
W Magento 2 Object Manager jest klasą, która została stworzona w celu uniknięcia wielokrotnego użycia szablonowego kodu odpowiedzialnego za zarządzanie instancjami obiektów.
Odpowiedzialność Object Managera
Object Managera oferuje następujące możliwości:
- Tworzenie obiektów, w tym także obiektów fabryk i proxy.
- Implementuje on wzorzec singleton, więc może zwrócić współdzieloną instancję na żądanie,
- Automatycznie inicjalizuje atrybuty w konstruktorach klas.
Object Manager obsługuje automaty zależności wstrzykiwane do klas poprzez argumenty konstruktora. Nie działa jednak w przypadku tworzenia instancji obiektów za pomocą operatora new.
Kiedy możemy korzystać z Object Managera w naszym kodzie?
W kodzie Magento 2 możemy znaleźć w wielu miejscach wykorzystanie klasy Object Manager. Niekoniecznie jednak zalecane jest, by to samo robić w pisanych przez nas rozszerzeniach. Bezpośrednio z klasy Object Managera możemy korzystać w sytuacjach gdy:
- kiedy potrzebujemy zainicjalizować obiekty w metodach magicznych, takich jak __wakeup(), __sleep() itd.,
- Możemy użyć Object Managera do zachowania kompatybilności wstecznej dla konstruktora,
- Object Manager może być zależnością w klasach służących do tworzenia obiektów takich jak fabryki czy proxy,
- W zasięgu globalnym, takim jak fixtury w testach integracyjnych.
Metody Object Managera
Interfejs Magento\Framework\ObjectManagerInterface zawiera trzy poniższe metody, które implementuje Object Manager:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework; /** * @api * @since 100.0.2 */ interface ObjectManagerInterface { /** * Create new object instance * * @param string $type * @param array $arguments * @return mixed */ public function create($type, array $arguments = []); /** * Retrieve cached object instance * * @param string $type * @return mixed */ public function get($type); /** * Configure object manager * * @param array $configuration * @return void */ public function configure(array $configuration); } |
Metoda get() działa jak singleton. Pozwala zwrócić za każdym razem tę samą instancję.
Metoda create() pozwala za każdym razem zainicjalizować nową instancję danego obiektu.
Metoda configure() pozwala na wprowadzenie dodatkowej konfiguracji, tutaj w dokumentacji mamy przykład, jak pominąć walidację reguły ACL podczas wykorzystywania klasy:
|
1 2 3 4 5 6 7 |
$objectManager = $bootstrap->getObjectManager(); $objectManager->configure([ 'preferences' => [ 'Magento\Framework\Authorization\PolicyInterface' => 'Magento\Framework\Authorization\Policy\DefaultPolicy' ] ]); |
Bezpośrednio w obiekcie Object Managera określino prefrence dla wybranego interfejsu pozwoliło na pominięcie walidacji ACL.
Inicjalizacja Object Managera
Jak każdą klasę, Object Managera możemy wstrzyknąć jako zależność konstruktora klasy, podając za argument interfejs Magento\Framework\ObjectManagerInterface:
|
1 2 3 4 5 6 |
protected $objectManager; public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager) { $this->objectManager = $objectManager; } |
W PHP 8 powyższy kod będzie wyglądał następująco:
|
1 2 3 |
public function __construct(protected \Magento\Framework\ObjectManagerInterface $objectManager) { } |
Odpowiedzialność za tworzenie obiektów spoczywa na klasach fabryk oraz proxy i do tych rodzajów klas wstrzykujemy Object Managera do konstruktora.
Możemy również pobrać bezpośrednio instancję Object Menagera za pomocą poniższego kodu:
|
1 |
\Magento\Framework\App\ObjectManager::getInstance(); |
Zwyczajowo nie potrzebujemy pracować bezpośrednio z Object Managerem w naszym kodzie, ponieważ framework sam to obsługuje i inicjalizuje zależności klas podawanych do konstruktora automatycznie.
Przykład metody magicznej
Przykład dla metody __wakeup() znajdziemy na przykład w klasie Magento\Eav\Model\Entity\Attribute\AbstractAttribute:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * @inheritdoc * @since 100.0.7 */ public function __wakeup() { parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_eavConfig = $objectManager->get(\Magento\Eav\Model\Config::class); $this->_eavTypeFactory = $objectManager->get(\Magento\Eav\Model\Entity\TypeFactory::class); $this->_storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class); $this->_resourceHelper = $objectManager->get(\Magento\Eav\Model\ResourceModel\Helper::class); $this->_universalFactory = $objectManager->get(\Magento\Framework\Validator\UniversalFactory ::class); $this->optionDataFactory = $objectManager->get(\Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class); $this->dataObjectProcessor = $objectManager->get(\Magento\Framework\Reflection\DataObjectProcessor::class); $this->dataObjectHelper = $objectManager->get(\Magento\Framework\Api\DataObjectHelper::class); } |
Przykład klasy fabryki
We wpisie na temat tworzeniem modeli dla operacji CRUD, wygenerowana klasa fabryki dla modelu Anna\Guestbook\Model\ResourceModel\Guestbook\Collection posiada następujący kod:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php namespace Anna\Guestbook\Model\ResourceModel\Guestbook; /** * Factory class for @see \Anna\Guestbook\Model\ResourceModel\Guestbook\Collection */ class CollectionFactory { /** * Object Manager instance * * @var \Magento\Framework\ObjectManagerInterface */ protected $_objectManager = null; /** * Instance name to create * * @var string */ protected $_instanceName = null; /** * Factory constructor * * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param string $instanceName */ public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Anna\\Guestbook\\Model\\ResourceModel\\Guestbook\\Collection') { $this->_objectManager = $objectManager; $this->_instanceName = $instanceName; } /** * Create class instance with specified parameters * * @param array $data * @return \Anna\Guestbook\Model\ResourceModel\Guestbook\Collection */ public function create(array $data = []) { return $this->_objectManager->create($this->_instanceName, $data); } } |
Ta wygląda podstawowa zawartość wygenerowanej klasy fabryki. Wzorując się na tym, możemy tworzyć swoje, bardziej rozbudowane wersje klas-fabryk.
Magento 2: preference - Web Programming
6 kwietnia 2024 @ 23:27
[…] w Magento 2 jest używany przez Object Manager, aby rozszerzyć domyślną implementację. Możesz użyć preference do określenia implementacji […]