yml services parameter injection dependency container autowiring symfony service dependency-injection yaml

parameter - symfony services



Llamar a un método en un servicio creado dinámicamente por un paquete (3)

Puede escribir un pase de compilación que tome la definición en cuestión y agregue la llamada a dicho método.

Estoy usando el paquete m6web_guzzle para registrar varios clientes http:

m6web_guzzlehttp: clients: myclient: timeout: 3 headers: "Accept": "application/json" delay: 0 verify: false

Quiero llamar a un método en un servicio que genera dinámicamente. En este caso, el nombre del servicio generado es:

@m6web_guzzlehttp.guzzle.handlerstack.myclient

Esto es lo que hago en mi constructor de servicios: (el tercer parámetro inyectado es ''@ m6web_guzzlehttp.guzzle.handlerstack.myclient'')

/** * @param array $parameters * @param Client $client * @param HandlerStack $handlerStack */ public function __construct(array $parameters, Client $client, HandlerStack $handlerStack) { $this->parameters = $parameters; $this->client = $client; $this->handlerStack->push(Middleware::retry([$this, ''retryDecider''])); }

Hasta ahora, funciona bien, pero ¿cómo puedo transferir la última línea (la llamada push ) en mi archivo services.yml ? ¿O otro método más limpio para registrar este controlador de reintento?


Así que los pasos del compilador fueron mencionados antes. Esa es una opción.

Usa fábricas para crear instancias

Pero casi puede expresar esto también directamente en la definición de su servicio. Digo casi , porque necesitará algún tipo de código ya que las definiciones de servicio de Symfony no pueden (AFAIK) evaluar a un Cierre, que es lo que necesitamos para Guzzle Middleware.

Escribí este services.yml como un ejemplo:

m6web_guzzlehttp.guzzle.handlerstack.myclient: class: GuzzleHttp/HandlerStack factory: [''GuzzleHttp/HandlerStack'', create] retry_decider: class: MyBundle/RetryDecider factory: [''MyBundle/RetryDecider'', createInstance] retry_handler: class: GuzzleHttp/Middleware factory: [''GuzzleHttp/Middleware'', retry] arguments: - ''@retry_decider'' handlerstack_pushed: parent: m6web_guzzlehttp.guzzle.handlerstack.myclient calls: - [push, [''@retry_handler'']]

¿Que es que?

  • m6web_guzzlehttp.guzzle.handlerstack.myclient - Su servicio dinámico - elimine del ejemplo ya que tiene esto ya creado.
  • retry_decider - Tu decisivo. createInstance un Cierre en el método createInstance . Puede agregar más parámetros si lo necesita, simplemente agregue argumentos a su YML.
  • retry_handler - Aquí retry_handler el middleware usando nuestro decisor
  • handlerstack_pushed : aquí push() nuestro controlador en la pila, utilizando el servicio dinámico como servicio principal.

Et voilà: tenemos la pila que definió el servicio dinámico, pero empujamos nuestro middleware de reintento.

Aquí está la fuente de nuestro decisor:

<?php namespace MyBundle; class RetryDecider { public static function createInstance() { return function() { // do your deciding here }; } }

-> Ahora tiene el handlerstack_pushed servicio que es la Pila completa.

Configurando más

Tenga en cuenta que puede agregar m6web_guzzlehttp.guzzle.handlerstack.myclient a parameters.yml :

parameters: baseHandlerStackService: m6web_guzzlehttp.guzzle.handlerstack.myclient

Luego, usa eso en handlerstack_pushed :

handlerstack_pushed: parent: "%baseHandlerStackService%" calls: - [push, [''@retry_handler'']]

Simplemente mejor así ;-)


En el archivo Extension.php su paquete, puede anular el método de carga y agregar:

$definition = $container->getDefinition(''m6web_guzzlehttp.guzzle.handlerstack.myclient''); $definition->addMethodCall(''push'', [Middleware::retry([$this, ''retryDecider''])]);