Znowu natknąłem się na ten problem dzisiaj i ważne jest, aby wiedzieć, że ten problem jest zgłaszany, ilekroć zależność w dół łańcucha inicjuje instancję, która musi znać stan aplikacji.
W wielu przypadkach błąd ten jest związany z sesją (ponieważ sesja musi znać stan aplikacji (frontend lub adminhtml)).
W moim przypadku musiałem mieć Magento\Tax\Api\TaxCalculationInterface
komendę CLI, ale wymaga to w pewnym momencie łańcucha zależności sesji klienta (prawdopodobnie w celu uzyskania grupy klientów).
Edycja: Znalazłem lepsze rozwiązanie przy użyciu serwerów proxy. Ale ze względu na historię, oto moja poprzednia odpowiedź:
Aby rozwiązać ten problem, nie dodałem tego interfejsu do mojego konstruktora, ale raczej jest on fabryczny:
/**
* @var \Magento\Tax\Api\TaxCalculationInterfaceFactory
*/
protected $taxCalculationFactory;
/**
* @param \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
*/
public function __construct(
\Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
) {
$this->taxCalculationFactory = $taxCalculationFactory;
}
W ten sposób klasa jest tworzona tylko w jednej metodzie, w której jej potrzebowałem, a nie w konstruktorze:
$taxCalculation = $this->taxCalculationFactory->create();
To rozwiązało problem w tym konkretnym przypadku.
A teraz odpowiedź za pomocą proxy:
Jeśli nie chcesz wyzwalać wszystkich zależności w dół łańcucha, powinieneś użyć proxy w swoim konstruktorze. Według oryginalnej dokumentacji :
... wstrzyknięcie konstruktora oznacza również, że reakcja łańcuchowa tworzenia instancji obiektu jest często wynikiem tworzenia obiektu.
i:
... Proxy rozszerzają inne klasy, by stały się ich leniwymi wersjami. Oznacza to, że rzeczywista instancja klasy, którą rozszerza serwer proxy, tworzona tylko po wywołaniu jednej z metod klasy.
Więc w mojej sytuacji, jedyne TaxCalculationInterface
, co musiałem zrobić, to utworzyć kalkulację podatkową jako przybliżenie w moim konstruktorze:
/**
* @var \Magento\Tax\Api\TaxCalculationInterface\Proxy
*/
protected $taxCalculation;
/**
* @param \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
*/
public function __construct(
\Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
) {
$this->taxCalculation = $taxCalculation;
}
W ten sposób moja klasa jest leniwie załadowana. To znaczy: jest on tworzony tylko wtedy, gdy wywołam jedną z jego metod. Na przykład:
$rate = $this->taxCalculation->getCalculatedRate($productRateId);