Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dive in the dependency injection container…

Dive in the dependency injection container…

Découvrons ce pattern et comment il fonctionne à travers des exemples réels. En prenant comme base le conteneur intégré à Symfony, mais en essayant d’ouvrir à toutes les solutions offertes par la communauté (aka PSR11), j’espère vous faire découvrir des capacités cachées dans votre application !

Les conteneurs d’injection de dépendance font parti intégrante des frameworks que nous utilisons tous les jours. On peut même dire que c’est le coeur de votre application. Aujourd'hui, on essaie d'automatiser au maximum leur configuration pour faciliter leur usage, mais comme ils permettent de créer, configurer, combiner des objets, ils gagnent à être mieux connus et maîtrisés.

Stéphane HULARD

October 26, 2020
Tweet

More Decks by Stéphane HULARD

Other Decks in Programming

Transcript

  1. D
    D

    View Slide

  2. S H
    S H
    Consultant, Formateur, Contributeur.
    @s_hulard
       

    View Slide

  3. U ?
    U ?

    View Slide

  4. P ?
    P ?

    View Slide

  5. C ?
    C ?

    View Slide

  6. U
    U
    class Moteur
    {
    public function __construct(string $name)
    {
    $this->name = $name;
    }
    }

    View Slide

  7. U
    U
    $container = [
    'moteur' => static function (): Moteur {
    return new Moteur('standard');
    },
    'v8' => new Moteur('v8')
    ];

    View Slide

  8. U
    U
    class Voiture
    {
    public function __construct()
    {
    $this->moteur = new Moteur('v8');
    }
    }

    View Slide

  9. U
    U
    $container['voiture'] = function () use ($container): Voiture {
    return new Voiture($container['moteur']);
    };
    $maVoiture = $container['voiture']();

    View Slide

  10. D S
    D S
    #services.yaml
    moteur:
    class: Moteur
    attributes:
    $name: 'standard'
    v8:
    class: Moteur
    attributes:
    $name: 'v8'
    voiture:
    class: Voiture
    attributes:
    $moteur: '@v8'

    View Slide

  11. I ?
    I ?
    Découplage, Rôle, Architecture.

    View Slide

  12. D ' PHP
    D ' PHP

    View Slide

  13. D
    D

    View Slide

  14. /* Laravel */
    class VoitureServiceProvider extends ServiceProvider
    {
    public function register()
    {
    $this->app->bind('moteur', function (): Moteur {
    return new Moteur('standard');
    });
    $this->app->bind('v8', new Moteur('v8'));
    $this->app->bind('voiture', function (Application $app): Moteur {
    return new Voiture($app->make('v8'));
    });
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    View Slide

  15. L
    L

    View Slide

  16. $container = new Pimple\Container();
    $container['moteur'] = function (): Moteur {
    return new Moteur('standard');
    };
    $container['v8'] = new Moteur('v8');
    $container['voiture'] = $container->factory(
    function(Pimple\Container $c) {
    new Voiture($c['v8']);
    }
    );
    $maVoiture = $container['voiture'];

    View Slide

  17. N PSR
    N PSR

    View Slide

  18. PSR
    PSR U
    U
    namespace Psr\Container;
    interface ContainerInterface
    {
    public function get($id);
    public function has($id);
    }

    View Slide

  19. E ?
    E ?

    View Slide

  20. IDD
    IDD I D D

    I D D

    interface Moteur {
    public function demarrer(): bool;
    }
    interface Voiture {
    public function allerA(Destination $destination): bool;
    }

    View Slide

  21. IDD
    IDD I D D

    I D D

    class MoteurV8 implements Moteur
    {
    public function demarrer() {
    $this->faireDuBruit();
    }
    }

    View Slide

  22. IDD
    IDD I D D

    I D D

    $container['v8'] = new MoteurV8();
    $container['voiture'] = function () use ($container): Voiture {
    return new Voiture($container['moteur']);
    };
    $maVoiture = $container['voiture']();

    View Slide

  23. P ' ?
    P ' ?

    View Slide

  24. L ?
    L ?
    class CustomQueryPass implements CompilerPassInterface
    {
    public function process(ContainerBuilder $container)
    {
    $container
    ->getDefinition(UploadExam::class)
    ->setArgument(
    '$files',
    $container->getDefinition('app.filesystem.tmp_dicom')
    );
    }
    }

    View Slide

  25. D S ?
    D S ?

    View Slide

  26. D S ?
    D S ?
    use App\Entity\MyUser;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\Security\Http\Attribute\CurrentUser;
    class SomeController extends AbstractController
    {
    public function index(#[CurrentUser] MyUser $user)
    {
    // ...
    }
    }

    View Slide

  27. C ?
    C ?
    Facilité, Documentation.

    View Slide

  28. View Slide