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étodocreateInstance
. 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''])]);