dunglas / DunglasActionBundle

Symfony controllers, redesigned
https://dunglas.fr/2016/01/dunglasactionbundle-symfony-controllers-redesigned/
MIT License
256 stars 14 forks source link

[proposal] Make AwareInterfaces injections #55

Closed JEDIBC closed 8 years ago

JEDIBC commented 8 years ago

Hi,

As there already is a ContainerAwareInterface injection in the DunglasActionExtension::registerClass() method, why not pushing it to the next level ?

The idea is to define in the configuration a list of *AwareInterface with the proper setter and container id to register the injection.

It will prevent the contructor boilerplate (most of the time) and is a convenient way of injecting dependancies & code snippets.

Interface example :

<?php
namespace Foo\Bar;

use Symfony\Component\Routing\RouterInterface;

/**
 * Interface RouterAwareInterface
 *
 * @package Foo\Bar
 */
interface RouterAwareInterface
{
    /**
     * @param RouterInterface $router
     */
    public function setRouter(RouterInterface $router);
}

Corresponding Trait:

<?php
namespace Foo\Bar;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;

/**
 * Class RouterTrait
 *
 * @package Foo\Bar
 */
trait RouterTrait
{
    /**
     * @var RouterInterface
     */
    protected $router;

    /**
     * @param RouterInterface $router
     */
    public function setRouter(RouterInterface $router)
    {
        $this->router = $router;
    }

    /**
     * Generates a URL from the given parameters.
     *
     * @param string $route         The name of the route
     * @param mixed  $parameters    An array of parameters
     * @param int    $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
     *
     * @return string The generated URL
     *
     * @see UrlGeneratorInterface
     */
    protected function generateUrl($route, $parameters = [], $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
    {
        return $this->router->generate($route, $parameters, $referenceType);
    }

    /**
     * Returns a RedirectResponse to the given URL.
     *
     * @param string $url    The URL to redirect to
     * @param int    $status The status code to use for the Response
     *
     * @return RedirectResponse
     */
    protected function redirect($url, $status = 302)
    {
        return new RedirectResponse($url, $status);
    }

    /**
     * Returns a RedirectResponse to the given route with the given parameters.
     *
     * @param string $route      The name of the route
     * @param array  $parameters An array of parameters
     * @param int    $status     The status code to use for the Response
     *
     * @return RedirectResponse
     */
    protected function redirectToRoute($route, array $parameters = [], $status = 302)
    {
        return $this->redirect($this->generateUrl($route, $parameters), $status);
    }
}

Configuration :

# app/config/config.yml

dunglas_action:
    interface_injections:
        'Foo\Bar\RouterAwareInterface':
            setter: 'setRouter'
            service: 'router'
dunglas commented 8 years ago

Symfony 3.2 will have setter injection support for autowiring. IMO it handles the same use case. WDYT?

JEDIBC commented 8 years ago

Looks fine for me as long as you activate the autowireSetter flag in DunglasActionExtension

dunglas commented 8 years ago

@JEDIBC yes it's planned!