Login to bookmark this video
Buy Access to Course
06.

Cómo funciona la autocableado

|

Share this awesome video!

|

Keep on Learning!

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Eh, ¡mira! ¡Es nuestro comando favorito!

bin/console debug:autowiring

Nos muestra una lista de los servicios que podemos autocablear en nuestro código. Pero, ¿cómo funciona realmente la autoconexión? Vamos a ejecutar otro comando:

bin/console debug:container

Esto nos da una enorme lista de servicios, y cualquier ID de servicio que resulte ser un nombre de clase o interfaz es autocableable. Esto significa que podemos indicarlo en el constructor de nuestro servicio y el contenedor de servicios inyectará ese servicio. Por el contrario, si un ID de servicio no es un nombre de interfaz o de clase, no es autoconectable. Esto es así por diseño, ya que la mayoría de los servicios son de bajo nivel y sólo existen para ayudar a otros servicios entre bastidores. Rara vez necesitaremos utilizar directamente esos servicios de bajo nivel, y por eso no podemos obtenerlos mediante autocableado. Y por eso debug:containertiene muchas más entradas que debug:autowiring.

Depurar el contenedor

El contenedor de servicios es básicamente una matriz gigante en la que cada servicio tiene un nombre único que apunta al objeto de servicio correspondiente. En el caso de twig, por ejemplo, el contenedor sabe que para instanciar este servicio, necesita crear una instancia de esta clase Twig\Environment. Y aunque aquí no veamos los argumentos, sabe exactamente cuáles debe pasar para instanciarlo. Como ventaja, si hacemos una petición del mismo servicio en más de un sitio, el contenedor de servicios sólo crea una instancia, por lo que tendremos exactamente la misma instancia en todas partes.

También te habrás fijado en estas clases de servicio. Este CacheInterface, por ejemplo, se utilizó antes como alias de nuestro servicio cache.app. Esto no es más que una forma de hacer que un servicio como cache.app sea autodireccionable. La gran mayoría de estos servicios utilizan la estrategia de nomenclatura snake case, así que para hacerlos autowireables en nuestro código, los bundles añaden algunos alias -nombres de clases, o interfaces- que podemos teclear en nuestro código. Así que los alias son básicamente como enlaces simbólicos que sólo hacen referencia a otros servicios. Sin embargo, puede haber ocasiones en las que haya varios servicios en el contenedor que implementen la misma clase o interfaz.

Grupo de caché personalizado

Para manejar esto, volvamos a nuestro código y creemos una reserva de caché personalizada. En config/packages/cache.yaml, aquí abajo, descomenta la clave pools, y en lugar de este ejemplo, di iss_location_pool: null.

22 lines | config/packages/cache.yaml
framework:
cache:
// ... lines 3 - 19
pools:
iss_location_pool: null

Ahora, en tu terminal, ejecuta:

bin/console debug:autowiring

Y... ¡compruébalo! Esta configuración ha añadido un nuevo servicio - iss_location_pool - que tiene el mismo CacheInterfaceque cache.app. Volvamos a src/Controller/MainController.php, dentro de homepage(), cambiemos el nombre de esta variable por $issLocationPool y mantengamos el mismo typehint CacheInterface. Copia ese nombre de variable y, aquí abajo, pégalo.

40 lines | src/Controller/MainController.php
// ... lines 1 - 13
class MainController extends AbstractController
{
// ... line 16
public function homepage(
// ... lines 18 - 19
CacheInterface $issLocationPool,
): Response {
// ... lines 22 - 24
$issData = $issLocationPool->get('iss_location_data', function (ItemInterface $item) use ($client): array {
// ... lines 26 - 30
});
// ... lines 32 - 37
}
}

Esto se llama "autocableado con nombre": nuestro contenedor de servicios mira el nombre de la variable y su typehint para inyectar el servicio correcto. Es bastante raro, pero también podemos verlo con nuestro servicio logger.

De vuelta a nuestro navegador, actualiza la página y comprueba el perfil de caché. Aquí está nuestro iss_location_pool y nuestro iss_location_data está escrito en ese pool. Si alguna vez necesitamos borrar la caché de este pool, en nuestro terminal, ejecuta:

bin/console cache:pool:clear iss_location_pool

Esto borrará la caché de este grupo concreto sin afectar a los demás grupos. ¡Muy práctico!

También podemos configurar este pool de forma diferente a los demás. Por ejemplo, vamos a establecer el tiempo de caducidad de nuestro nuevo pool en el archivo de configuración. En cache.yaml, en lugar de null, en una nueva línea, escribe default_lifetime: 5.

23 lines | config/packages/cache.yaml
framework:
cache:
// ... lines 3 - 19
pools:
iss_location_pool:
default_lifetime: 5

El 5 está en segundos. Esto debería afectar a todos los elementos de caché de esta reserva. Ahora, en MainController.php, podemos eliminar $item->expiresAfter(). También podemos deshacernos por completo de este argumento $item.

38 lines | src/Controller/MainController.php
// ... lines 1 - 13
class MainController extends AbstractController
{
// ... line 16
public function homepage(
// ... lines 18 - 20
): Response {
// ... lines 22 - 24
$issData = $issLocationPool->get('iss_location_data', function () use ($client): array {
$response = $client->request('GET', 'https://api.wheretheiss.at/v1/satellites/25544');
return $response->toArray();
});
// ... lines 30 - 35
}
}

Para asegurarnos de que esto funciona, en nuestro navegador, actualiza de nuevo la página de inicio y... no hay errores. ¡Funciona!

Siguiente: Hablemos de los entornos: conjuntos de configuraciones que nos ayudan a desarrollar localmente frente a la producción.