Buy Access to Course
19.

¡Los controladores también son servicios!

|

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

Abre src/Controller/VinylController.php. ¡Puede que sea obvio o no, pero nuestras clases de controlador también son servicios en el contenedor! ¡Sí! Se sienten especiales porque son controladores... pero en realidad sólo son viejos y aburridos servicios como todo lo demás. Bueno, excepto que tienen un superpoder que no tiene nada más: la capacidad de autoconectar argumentos en sus métodos de acción. Normalmente, el autocableado sólo funciona con el constructor.

Vinculación de los argumentos de la acción

Los métodos de acción funcionan realmente como los constructores en lo que respecta a la autoconexión. Por ejemplo, añade un argumento bool $isDebug a la acción browse()... y a continuación dump($isDebug):

38 lines | src/Service/MixRepository.php
// ... lines 1 - 6
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
// ... lines 9 - 13
class MixRepository
{
// ... lines 16 - 24
public function findAll(): array
{
$output = new BufferedOutput();
$this->twigDebugCommand->run(new ArrayInput([]), $output);
dd($output);
// ... lines 30 - 35
}
}

Y eso... ¡no funciona! Hasta ahora, las únicas dos cosas que sabemos que podemos tener como argumentos de nuestras "acciones" son (A), cualquier comodín en la ruta como$slug y (B) los servicios autocableables, como MixRepository.

Pero ahora, vuelve a config/services.yaml y descomenta el global bind de antes:

32 lines | config/services.yaml
// ... lines 1 - 12
services:
# default configuration for services in *this* file
_defaults:
// ... lines 16 - 17
bind:
'bool $isDebug': '%kernel.debug%'
// ... lines 20 - 32

Esta vez... ¡funciona!

Añadir un constructor

Yendo en la otra dirección, como los controladores son servicios, puedes absolutamente tener un constructor si quieres. Movamos MixRepository y $isDebug a un nuevo constructor. Cópialos, quítalos... añade public function __construct(), pégalos... y luego los pondré en sus propias líneas. Para convertirlos en propiedades, añadeprivate delante de cada uno:

51 lines | src/Controller/VinylController.php
// ... lines 1 - 10
class VinylController extends AbstractController
{
public function __construct(
private bool $isDebug,
private MixRepository $mixRepository
)
{}
// ... lines 18 - 36
#[Route('/browse/{slug}', name: 'app_browse')]
public function browse(string $slug = null): Response
{
// ... lines 40 - 48
}
}

De nuevo abajo, sólo tenemos que asegurarnos de cambiar a dump($this->isDebug) y añadir $this-> delante de mixRepository:

51 lines | src/Controller/VinylController.php
// ... lines 1 - 10
class VinylController extends AbstractController
{
public function __construct(
private bool $isDebug,
private MixRepository $mixRepository
)
{}
// ... lines 18 - 36
#[Route('/browse/{slug}', name: 'app_browse')]
public function browse(string $slug = null): Response
{
dump($this->isDebug);
// ... lines 41 - 42
$mixes = $this->mixRepository->findAll();
// ... lines 44 - 48
}
}

¡Bien! Si probamos esto ahora... ¡funciona bien!

Normalmente no sigo este enfoque... principalmente porque añadir argumentos al método de acción es muy fácil. Pero si necesitas un servicio u otro valor en cada método de acción de tu clase, definitivamente puedes limpiar tu lista de argumentos inyectándola a través del constructor. Voy a eliminar ese dump().

A continuación, vamos a hablar de las variables de entorno y de la finalidad del archivo .env que hemos visto antes. Estas cosas serán cada vez más importantes a medida que hagamos nuestra aplicación más y más realista.