Hoy he vuelto a tropezar con este problema y es importante saber que este problema se produce cada vez que una dependencia en la cadena inicia una instancia que necesita conocer el estado de la aplicación.
En muchos casos, este error está vinculado a la sesión (ya que la sesión necesita conocer el estado de la aplicación (frontend o adminhtml)).
En mi caso, necesitaba tener Magento\Tax\Api\TaxCalculationInterface
un comando CLI, pero esto requiere en algún momento de su cadena de dependencia la sesión del cliente (probablemente para obtener el grupo de clientes).
Editar: encontré una mejor solución usando proxies. Pero por el bien de las historias, aquí está mi respuesta anterior:
Para resolver esto, no incluí esta interfaz en mi constructor, sino que es de fábrica:
/**
* @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 esta manera, la clase solo se instancia en el método donde lo necesitaba, y ya no en el constructor:
$taxCalculation = $this->taxCalculationFactory->create();
Esto resolvió el problema para mí en este caso particular.
Y ahora la respuesta usando un proxy:
Si no desea activar todas las dependencias en la cadena, debe usar un proxy en su constructor. Según la documentación original :
... la inyección del constructor también significa que una reacción en cadena de creación de instancias de objeto es a menudo el resultado cuando se crea un objeto.
y:
... Los proxies extienden otras clases para convertirse en versiones perezosas de ellos. Es decir, una instancia real de la clase que un proxy extiende, creada solo después de que se llame a uno de los métodos de la clase.
Entonces, en mi situación, con el TaxCalculationInterface
, todo lo que tenía que hacer era instanciar mi cálculo de impuestos como proxy en mi constructor:
/**
* @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 esta manera, mi clase está perezosa. Es decir: solo se crea una instancia tan pronto como llamo a uno de sus métodos. Por ejemplo:
$rate = $this->taxCalculation->getCalculatedRate($productRateId);