Aujourd'hui, je suis encore tombé sur ce problème et il est important de savoir que ce problème est posé chaque fois qu'une dépendance découle d'une instance qui nécessite de connaître l'état de l'application.
Dans de nombreux cas, cette erreur est liée à la session (car la session doit connaître l'état de l'application (frontend ou adminhtml)).
Dans mon cas, je devais avoir Magento\Tax\Api\TaxCalculationInterface
une commande CLI, mais cela nécessite à un moment de sa chaîne de dépendance la session client (probablement pour obtenir le groupe de clients).
Edit: J'ai trouvé une meilleure solution en utilisant des proxies. Mais pour les histoires, voici ma réponse précédente:
Pour résoudre ce problème, je n'ai pas inclus cette interface dans mon constructeur, mais plutôt son usine:
/**
* @var \Magento\Tax\Api\TaxCalculationInterfaceFactory
*/
protected $taxCalculationFactory;
/**
* @param \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
*/
public function __construct(
\Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
) {
$this->taxCalculationFactory = $taxCalculationFactory;
}
De cette façon, la classe n'est instanciée que dans la seule méthode où j'en avais besoin, et non plus dans le constructeur:
$taxCalculation = $this->taxCalculationFactory->create();
Cela a résolu le problème pour moi dans ce cas particulier.
Et maintenant la réponse en utilisant un proxy:
Si vous ne voulez pas déclencher toutes les dépendances en aval de la chaîne, vous devez utiliser un proxy dans votre constructeur. Selon la documentation originale :
... l'injection de constructeur signifie également qu'une réaction en chaîne d'instanciation d'objet est souvent le résultat de la création d'un objet.
et:
... Les mandataires étendent les autres classes pour en devenir des versions paresseuses. C'est-à-dire qu'une instance réelle de la classe qu'un proxy étend est créée uniquement après que l'une des méthodes de la classe a été appelée.
Donc, dans ma situation, avec TaxCalculationInterface
, tout ce que j'avais à faire était d'instancier mon calcul de taxe comme proxy dans mon constructeur:
/**
* @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;
}
De cette façon, ma classe est paresseuse chargée. C'est-à-dire: il n'est instancié que lorsque j'appelle l'une de ses méthodes. Par exemple:
$rate = $this->taxCalculation->getCalculatedRate($productRateId);