Slide 1

Slide 1 text

Fonctionnement interne du container d'injection de dépendance de Symfony Sarah Khalil 17 avril 2015 Symfony Tunisie 2015 Cycle de vie du container d’Injection de Dépendance

Slide 2

Slide 2 text

Sarah Khalil Responsable @saro0h SensioLabs Qui suis-je ?

Slide 3

Slide 3 text

Je ne parlerai pas de configuration, ni de bonnes pratiques, ni de la manipulation de services avec Symfony. Un tout petit peu

Slide 4

Slide 4 text

Parcourir la construction du container. Identifier les points d’extension. Du code, beaucoup de code.

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Qu’est-ce que l’injection de dépendance ?

Slide 8

Slide 8 text

Principes de Programmation Orientée Objet SOLID

Slide 9

Slide 9 text

SOLID : Single responsability principle Une classe ne doit avoir qu’une seule responsabilité.

Slide 10

Slide 10 text

SOLID : Open/Closed principle Une classe doit être ouverte à l’extension, fermée à la modification.

Slide 11

Slide 11 text

SOLID : Liskov substitution principle Remplacer une dépendance sans rien affecter. Lors de la spécialisation, conserver les même prototypes de méthodes.

Slide 12

Slide 12 text

Plusieurs interfaces spécifiques plutôt qu'une seule interface générale. SOLID : Interface segregation principle

Slide 13

Slide 13 text

Ne pas instancier les dépendances. Abstraction (Interface/Abstract) Implémentation SOLID : Dependency Injection principle Changer facilement d’implémentation Dépendance = Objet

Slide 14

Slide 14 text

Dependency Injection Component

Slide 15

Slide 15 text

Quelques chiffres • 13 189 / 253 901LOC • 145 fichiers • 121 classes

Slide 16

Slide 16 text

Un peu de vocabulaire • Service = Instance de classe, un objet. • Container d’injection dépendance Objet PHP en charge de l’instanciation des services.

Slide 17

Slide 17 text

Types d’injection • Constructeur • Setter • Propriété Le plus utilisé

Slide 18

Slide 18 text

Types d’injection : Constructeur (1/3) class  NewsletterManager   {          private  $mailer;          public  function  __construct(MailerInterface  $mailer)          {                  $this-­‐>mailer  =  $mailer;          }   }                                                                                                         Dépendance Déclaration de services Dépendance obligatoire

Slide 19

Slide 19 text

Types d’injection : Setter (2/3) class  NewsletterManager   {          private  $mailer;          public  function  setMailer(MailerInterface  $mailer)          {                  $this-­‐>mailer  =  $mailer;          }   }                                                                                                                                                                       Déclaration de services Dépendance Dépendance optionnelle

Slide 20

Slide 20 text

Types d’injection : Propriété (3/3) class  NewsletterManager   {          public  $mailer;   }                                                                                                           Déclaration de services Dépendance Non conseillé

Slide 21

Slide 21 text

Types d’injection Types + - Constructeur • Typage • Certain d’avoir la dépendance • Toujours passer la dépendance • Sauf si $dep=null Setter • Dépendance optionnelle • Typage • Vérifier que la dépendance est bien là. Propriété - • Aucun moyen de s’assurer que la dépendance est bien injectée. • Typage impossible.

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Ce que nous avons l’habitude faire                                           use  Symfony\Bundle\FrameworkBundle\Controller\Controller;   class  DefaultController  extends  Controller   {          public  function  mailAction()          {                  $this-­‐>get('my_mailer')-­‐>sendEmail();          }   } étape 1: déclaration de service étape 2 : faire appel au service

Slide 24

Slide 24 text

Comment ça marche ?

Slide 25

Slide 25 text

Suivez la carte, je vous emmène ! Front Controller Kernel ContainerBuilder Container Vous êtes ici

Slide 26

Slide 26 text

3 Grandes étapes 1. Construction du container builder 2. Compilation du container builder 3. Récupérer le container

Slide 27

Slide 27 text

C’est parti ! Front Controller Kernel ContainerBuilder Container Vous êtes ici

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Front Controller web/app.php ou web/app_dev.php use  Symfony\Component\ClassLoader\ApcClassLoader;   use  Symfony\Component\HttpFoundation\Request;   $loader  =  require_once  __DIR__.'/../app/bootstrap.php.cache';   require_once  __DIR__.'/../app/AppKernel.php';   $kernel  =  new  AppKernel('prod',  false);   $kernel-­‐>loadClassCache();   $request  =  Request::createFromGlobals();   $response  =  $kernel-­‐>handle($request);   $response-­‐>send();   $kernel-­‐>terminate($request,  $response); Build Container

Slide 30

Slide 30 text

Vers le kernel Front Controller Kernel ContainerBuilder Container Vous êtes ici AppKernel

Slide 31

Slide 31 text

app/AppKernel • Etend Symfony\Component\HttpKernel\Kernel •registerBundles() •registerContainerConfiguration(LoaderInterface $loader)

Slide 32

Slide 32 text

Front controller web/app.php ou web/app_dev.php use  Symfony\Component\ClassLoader\ApcClassLoader;   use  Symfony\Component\HttpFoundation\Request;   $loader  =  require_once  __DIR__.'/../app/bootstrap.php.cache';   require_once  __DIR__.'/../app/AppKernel.php';   $kernel  =  new  AppKernel('prod',  false);   $kernel-­‐>loadClassCache();   $request  =  Request::createFromGlobals();   $response  =  $kernel-­‐>handle($request);   $response-­‐>send();   $kernel-­‐>terminate($request,  $response);

Slide 33

Slide 33 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container public  function  handle(Request  $request  […])   {          if  (false  ===  $this-­‐>booted)  {                   $this-­‐>boot();          }          return  […]   }

Slide 34

Slide 34 text

Kernel Symfony\Component\HttpKernel\Kernel public  function  boot()   {      if  (true  ===  $this-­‐>booted)  {              return;      }      […]       $this-­‐>initializeBundles();      $this-­‐>initializeContainer();      foreach  ($this-­‐>getBundles()  as  $bundle)  {              $bundle-­‐>setContainer($this-­‐>container);              $bundle-­‐>boot();      }      $this-­‐>booted  =  true;   } Appelle registerBundles() d’AppKernel pour récupérer tous les bundles à initialiser

Slide 35

Slide 35 text

Construction du Container Builder 1ère étape

Slide 36

Slide 36 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container public  function  boot()   {      if  (true  ===  $this-­‐>booted)  {              return;      }      […]      $this-­‐>initializeBundles();       $this-­‐>initializeContainer();      foreach  ($this-­‐>getBundles()  as  $bundle)  {              $bundle-­‐>setContainer($this-­‐>container);              $bundle-­‐>boot();      }      $this-­‐>booted  =  true;   }

Slide 37

Slide 37 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container protected  function  initializeContainer()   {           $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 38

Slide 38 text

Kernel getContainerClass() Build Container Construit le nom de la classe de container app(Prod|Dev)(Debug)ProjectContainer

Slide 39

Slide 39 text

app(Prod|Dev)(Debug)ProjectContainer Build Container class  appDevDebugProjectContainer  extends  Container   {          //…          public  function  __construct()          {                  $this-­‐>methodMap  =  array(                          'user_manager'  =>  'getUserManagerService',                          //…            }          //…          protected  function  getUserManagerService()          {                  return  $this-­‐>services['user_manager']  =                            new  \AppBundle\Service\UserManager();          }   }

Slide 40

Slide 40 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();    $cache  =  new  ConfigCache(          $this-­‐>getCacheDir().’/'.$class.’.php',          $this-­‐>debug    );          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 41

Slide 41 text

Un petit détour Symfony\Component\Config\ConfigCache Build Container Son métier : gestion des fichiers mis en cache isFresh() write() getMetaFile() On y reviendra

Slide 42

Slide 42 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  ( !$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 43

Slide 43 text

isFresh() Symfony\Component\Config\ConfigCache Build Container Le cache est frais si : • app(Prod|Dev)(Debug)ProjectContainer.php existe • l’application n’est pas en mode debug • si le fichier app(Prod|Dev) (Debug)ProjectContainer.php.meta existe • Ressources n’ont pas changées depuis la dernier boot du kernel et ou et app(Prod|Dev)(Debug)ProjectContainer.php.meta contient la liste des resources ajoutées au containerBuilder, serialisée

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

Moitié du voyage Front Controller Kernel ContainerBuilder Container Vous êtes ici

Slide 46

Slide 46 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                   $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 47

Slide 47 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 48

Slide 48 text

Kernel::buildContainer()

Slide 49

Slide 49 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 50

Slide 50 text

buildContainer() 1/6 Symfony\Component\HttpKernel\Kernel Build Container Vérifie que le dossier de cache est accessible en écriture. 1

Slide 51

Slide 51 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 52

Slide 52 text

buildContainer() /6 Symfony\Component\HttpKernel\Kernel Build Container Instancie le ContainerBuilder. 2

Slide 53

Slide 53 text

Instancier le ContainerBuilder Symfony\Component\HttpKernel\Kernel Build Container Si ocramius/proxy-manager • Permet le lazy loading des services. • Un ProxyInstanciator se charge de n’instancier un service que si c’est vraiment nécessaire. lazy=true

Slide 54

Slide 54 text

Lazy loading Service A Service B Sans lazy loading : ce service est instancé même s’il n’est pas utilisé. Avec le lazy loading : ce service n’est instancé que s’il y a utilisation concrète.

Slide 55

Slide 55 text

! Overhead non négligeable blackfire.io

Slide 56

Slide 56 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 57

Slide 57 text

buildContainer() 3/6 Symfony\Component\HttpKernel\Kernel Build Container Kernel::prepareContainer() Pour chaque bundle • Chargement des classes d’extensions [1] ! • Appel de la méthode build() [2] ! • Passe de compilation chargée d’appeler la méthode load() de toutes les extensions 3

Slide 58

Slide 58 text

namespace  AppBundle\DependencyInjection;   use  […]   class  AppExtension  extends  Extension   {      public  function  load(array  $configs,  ContainerBuilder   $container)      {          $configuration  =  new  Configuration();          $config  =  $this-­‐>processConfiguration($configuration,   $configs);          $loader  =  new  Loader\XmlFileLoader($container,  new   FileLocator(__DIR__.'/../Resources/config'));          $loader-­‐>load('services.xml');      }   }   Classe d’extension Rappel

Slide 59

Slide 59 text

prepareContainer() Symfony\Component\HttpKernel\Kernel Build Container Point d’extension ! [1] Bundle::getContainerExtension() [NamespaceDuBundle]\DependencyInjection\[NomDuBundle]Extension

Slide 60

Slide 60 text

prepareContainer() Symfony\Component\HttpKernel\Kernel Build Container Point d’extension ! [2] Bundle::build(ContainerBuilder) Enregistrer les passes de compilation, d’autres extensions… tout ce que l’on souhaite ajouter au containerBuilder.

Slide 61

Slide 61 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 62

Slide 62 text

Symfony\Component\HttpKernel\Kernel Build Container Kernel::registerContainerConfiguration(LoaderInterface $loader) Tout ce qui est dans config_*.yml est mergé dans le container. [3] buildContainer() 3/6 4

Slide 63

Slide 63 text

registerContainerConfiguration() Symfony\Component\HttpKernel\Kernel Build Container Point d’extension ! [3] Kernel::registerContainerConfiguration() Enregistrer de la configuration dynamiquement, en fonction de l’environnement par exemple.

Slide 64

Slide 64 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 65

Slide 65 text

Symfony\Component\HttpKernel\Kernel Build Container • Ajout d’une passe de compilation responsable de l’écriture du classes.map. • Ne contient que les classes d’extension. • Usage uniquement interne. buildContainer() 3/6 5

Slide 66

Slide 66 text

protected  function  buildContainer()   {          //  check  if  the  cache  directory  is  writable          $container  =  $this-­‐>getContainerBuilder();          $container-­‐>addObjectResource($this);          $this-­‐>prepareContainer($container);          $containerLoader  =  $this-­‐>getContainerLoader($container);          $cont  =  $this-­‐>registerContainerConfiguration($containerLoader);          if  (null  !==  $cont)  {                  $container-­‐>merge($cont);          }          $container-­‐>addCompilerPass(new  AddClassesToCachePass($this));          $container-­‐>addResource(new  EnvParametersResource(‘SYMFONY__’);          return  $container;   } Kernel Symfony\Component\HttpKernel\Kernel Build Container 2 1 3 4 5 6

Slide 67

Slide 67 text

Symfony\Component\HttpKernel\Kernel Build Container Variables d’environnements dans $_SERVER et commençant par SYMFONY__ buildContainer() 3/6 6

Slide 68

Slide 68 text

On y arrive ! Front Controller Kernel ContainerBuilder Container Vous êtes ici

Slide 69

Slide 69 text

Compilation du Container Builder 2ième étape

Slide 70

Slide 70 text

ContainerBuilder Symfony\Component\DependencyInjection Compile protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                   $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 71

Slide 71 text

ContainerBuilder Symfony\Component\DependencyInjection Compile • Récupération du compiler • Symfony\Component\DependencyInjection\Compiler • process($containerBuilder) de toutes les passes de compilations [4] • Résout les paramètres « %xxxxxx% » • Ajout des paramètres dans le FrozenParameterBag Lecture seule

Slide 72

Slide 72 text

ContainerBuilder Symfony\Component\DependencyInjection Compile Le container est à l’état « frozen »

Slide 73

Slide 73 text

Passe de compilation Compiler pass Compile Modifier la définition de services dans le ContainerBuilder http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html Point d’extension ! [4] CompilerPassInterface::process() http://afsy.fr/avent/2013/05-conteneur-de-services-creer-ses-propres-tags

Slide 74

Slide 74 text

Récupérer le container 3ième étape

Slide 75

Slide 75 text

On y arrive ! Front Controller Kernel ContainerBuilder Container Vous êtes ici

Slide 76

Slide 76 text

ContainerBuilder Symfony\Component\DependencyInjection récupérer le container protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                   $this-­‐>dumpContainer(                  $cache,                  $container,                  $class,                  $this-­‐>getContainerBaseClass()          );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 77

Slide 77 text

• Symfony\Component\DependencyInjection\Dumper\PhpDumper • Si => le proxyDumper est utilisé. • Le code est créé pour remplir le fichier app(Prod|Dev)(Debug)ProjectContainer. • Le fichier est écrit. récupérer le container Kernel Symfony\Component\HttpKernel

Slide 78

Slide 78 text

app(Prod|Dev)(Debug)ProjectContainer.php class  appDevDebugProjectContainer  extends  Container   {          //…          public  function  __construct()          {                  $this-­‐>methodMap  =  array(                          'user_manager'  =>  'getUserManagerService',                          //…            }          //…          protected  function  getUserManagerService()          {                  return  $this-­‐>services['user_manager']  =                            new  \AppBundle\Service\UserManager();          }   } récupérer le container

Slide 79

Slide 79 text

Hurray Container

Slide 80

Slide 80 text

On y est ! Front Controller Kernel ContainerBuilder Container Vous êtes ici

Slide 81

Slide 81 text

ContainerBuilder Symfony\Component\DependencyInjection Compile protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }           require_once  $cache;      $this-­‐>container  =  new  $class();          $this-­‐>container-­‐>set('kernel',  $this);                    […]   }

Slide 82

Slide 82 text

ContainerBuilder Symfony\Component\DependencyInjection protected  function  initializeContainer()   {          $class  =  $this-­‐>getContainerClass();          $cache  =  new  ConfigCache($this-­‐>getCacheDir().'/'.$class.'.php',  $this-­‐>debug);          $fresh  =  true;          if  (!$cache-­‐>isFresh())  {                  $container  =  $this-­‐>buildContainer();                  $container-­‐>compile();                  $this-­‐>dumpContainer(                          $cache,                          $container,                          $class,                          $this-­‐>getContainerBaseClass()                  );                  $fresh  =  false;          }          require_once  $cache;          $this-­‐>container  =  new  $class();         $this-­‐>container-­‐>set('kernel',  $this);                    […]   } Service synthetic

Slide 83

Slide 83 text

Comment cela se finit ?

Slide 84

Slide 84 text

Kernel Symfony\Component\HttpKernel\Kernel Build Container public  function  boot()   {      if  (true  ===  $this-­‐>booted)  {              return;      }      […]      $this-­‐>initializeBundles();      $this-­‐>initializeContainer();      foreach  ($this-­‐>getBundles()  as  $bundle)  {              $bundle-­‐>setContainer($this-­‐>container);              $bundle-­‐>boot();      }      $this-­‐>booted  =  true;   }

Slide 85

Slide 85 text

Récapitulons

Slide 86

Slide 86 text

3 Grandes étapes 1. Construction du container builder 2. Compilation du container builder 3. Récupérer le container

Slide 87

Slide 87 text

Points d’extension disponibles Quand ? Réécriture Kernel:buildContainer() Étape 1 Bundle::getContainerExtension() Kernel:buildContainer() Étape 1 Bundle::build() Kernel:buildContainer() Étape 1 AppKernel::registerContainerConfiguration() ContainerBuilder::compile() Étape 2 CompilerPassInterface::process()

Slide 88

Slide 88 text

No content

Slide 89

Slide 89 text

@saro0h