Slide 1

Slide 1 text

Plongée dans l'injection de dépendances de Symfony Avril 2019 SymfonyLive Tunis

Slide 2

Slide 2 text

Titouan Galopin @tgalopin 2 insight.symfony.com

Slide 3

Slide 3 text

3 Une question m’obnubile …

Slide 4

Slide 4 text

4 Pourquoi l’architecture logicielle est-elle importante ?

Slide 5

Slide 5 text

5 Qu’est-ce qui différencie du code bien conçu et du code mal conçu ?

Slide 6

Slide 6 text

6 La gestion du changement

Slide 7

Slide 7 text

7 Une architecture logicielle de qualité, c’est une architecture qui accompagne le changement

Slide 8

Slide 8 text

8 Changement ... Dans le temps Dans l’environnement

Slide 9

Slide 9 text

9 Comment concevoir une architecture qui accompagne le changement ?

Slide 10

Slide 10 text

10 Créer des classes qui se partagent les responsabilités

Slide 11

Slide 11 text

11 Elles interagissent pour constituer l’application

Slide 12

Slide 12 text

12 Elles sont modifiables indépendamment les unes des autres

Slide 13

Slide 13 text

13 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine

Slide 14

Slide 14 text

14 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine

Slide 15

Slide 15 text

15 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine Contrats (= Interfaces)

Slide 16

Slide 16 text

16 interface PersisterInterface { /* ... */ } interface MailerInterface { /* ... */ } class RegistrationManager { private $persister; private $mailer; public function __construct( PersisterInterface $persister, MailerInterface $mailer ) { $this->persister = $persister; $this->mailer = $mailer; } public function register() {/* ... */} }

Slide 17

Slide 17 text

17 C’est l’injection de dépendances

Slide 18

Slide 18 text

18 Encapsuler des objets dans d’autres pour créer des comportements complexes

Slide 19

Slide 19 text

19 Faciliter le changement par l’utilisation de contrats

Slide 20

Slide 20 text

20 Mais créer un objet devient plus compliqué

Slide 21

Slide 21 text

21 $manager = new RegistrationManager( new Persister( new Doctrine(/* ... */) ), new Mailer( new Twig(/* ... */), new SwiftMailer(/* ... */) ) );

Slide 22

Slide 22 text

22 Symfony DependencyInjection

Slide 23

Slide 23 text

23 Objectif : permettre la création aisé d’instances de classes

Slide 24

Slide 24 text

24 Configurer ce graphe de dépendances entre classes

Slide 25

Slide 25 text

25 interface PersisterInterface { /* ... */ } interface MailerInterface { /* ... */ } class RegistrationManager { private $persister; private $mailer; public function __construct( PersisterInterface $persister, MailerInterface $mailer ) { $this->persister = $persister; $this->mailer = $mailer; } public function register() {/* ... */} }

Slide 26

Slide 26 text

26 $manager = new RegistrationManager( new Persister( new Doctrine(/* ... */) ), new Mailer( new Twig(/* ... */), new SwiftMailer(/* ... */) ) ); Objectif

Slide 27

Slide 27 text

27 Fonctionnement général 1 Configuration 2 Compilation 3 Utilisation

Slide 28

Slide 28 text

28 1. Configuration services.yaml

Slide 29

Slide 29 text

29 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine

Slide 30

Slide 30 text

30 services: # ... App\Persister: arguments: ['@doctrine'] App\Mailer: arguments: ['@twig', '@swiftmailer] App\RegistrationManager: arguments: ['@App\Persister', '@App\Mailer']

Slide 31

Slide 31 text

31 Depuis Symfony 4 : Autodiscovery Autowiring

Slide 32

Slide 32 text

32 services: _defaults: autowire: true App\: resource: '../src/*'

Slide 33

Slide 33 text

33 services: _defaults: autowire: true App\: resource: '../src/*' Autodiscovery : importe toutes les classes dans src/ en tant que noeuds du graphe

Slide 34

Slide 34 text

34 services: _defaults: autowire: true App\: resource: '../src/*' Autodiscovery : importe toutes les classes dans src/ en tant que noeuds du graphe Autowiring : créé les liens entre les noeuds du graphe automatiquement

Slide 35

Slide 35 text

35 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine Autodiscovery Autowiring

Slide 36

Slide 36 text

36 2. Compilation

Slide 37

Slide 37 text

37 On a maintenant un graphe de dépendances

Slide 38

Slide 38 text

38 On sait donc créer une instance de classe

Slide 39

Slide 39 text

39 Mais passer par le graphe directement, c’est lent

Slide 40

Slide 40 text

40 Compiler le graphe de dépendances = Le transformer en PHP

Slide 41

Slide 41 text

41

Slide 42

Slide 42 text

42 Nouvelle possibilité : modifier le graphe entre la configuration et l’utilisation

Slide 43

Slide 43 text

43 CompilerPass = Modification du graphe au moment de la compilation

Slide 44

Slide 44 text

44 3. Utilisation

Slide 45

Slide 45 text

45 Transparente !

Slide 46

Slide 46 text

46 Les points d’entrée de votre application (contrôleurs, commandes, …) font partie du graphe !

Slide 47

Slide 47 text

47 class RegistrationController extends AbstractController { /** * @Route("/register", name="register") */ public function register(RegistrationManager $manager) { // ... $manager->register($user); // ... } }

Slide 48

Slide 48 text

48 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine RegistrationController

Slide 49

Slide 49 text

49 Beaucoup d’autres fonctionnalités Tags, bindings, named autowiring aliases, autoconfiguration, factories, decorators, ...

Slide 50

Slide 50 text

50 Contribuez ! symfony.com/support => Slack Pinguez Nicolas Grekas

Slide 51

Slide 51 text

51 Merci ! Venez me voir au stand SymfonyInsight ! ▪ Twitter : @titouangalopin ▪ Github : @tgalopin ▪ titouan.galopin@symfony.com