D8 : Le conteneur d'injection de dépendances aux petits oignons !

D8 : Le conteneur d'injection de dépendances aux petits oignons !

Deep dive into the Dependency Injection Container in Drupal 8.

8d26b5d9c10abb80a42e6ba9dfa47dfa?s=128

Perussel Nicolas

February 16, 2019
Tweet

Transcript

  1. DRUPAL CAMP PARIS 2019 Le DIC aux petits oignons !

    Le conteneur d’injections de dépendances dans Drupal 8
  2. Summary 2 01. 02. 03. 04. 05. 06. DIC inside

    Drupal 8 Some generic & Symfony vocabulary How does the DIC work in D8 ? Altering the DIC is easy ! The bad side… Conclusion p.3–6 p.7-13 p.14-23 p.24-27 p.28-30 p.30 @mamoot64 nicolas.perussel@ekino.com
  3. 522 3

  4. Dependency Container Injection inside Drupal 8

  5. HISTORY 5 Mark Sonnabaum (msonnabaum) opened an issue about shared

    filesystem. Fabian Franz (Fabianx) was assigned on it. Work on: 29 May to 23 August 2015 è File system cache is hard to invalidate on multiple web heads è Reading from the shared network is slow and insecured. è Needs to be synchronized (Ex: module is disabled) !!! EVERYTHING MUST BE DYNAMIC AT RUN-TIME !!!
  6. THE GOAL 6 Have a custom « Dumper » è

    PHP Array Friendly The Dumper « PHPArrayContainer » can be stored in differents locations (Redis, Db, Memcache…) Must be built on run-time Must be optimized for speed
  7. 7 Drupal Component Drupal Implementation Extends / Implements

  8. Some generic & Symfony vocabulary

  9. DIC A Dependency Injection Container is an object that knows

    how to instantiate and configure objects. And to be able to do its job, it needs to knows about the constructor arguments and the relationships between the objects. Fabien Potencier 9 http://fabien.potencier.org/do-you-need-a-dependency-injection-container.html
  10. Definition It’s a dedicated class which let you configure services

    for the Service Container. è Symfony\Component\DependencyInjection\Definition; https://symfony.com/doc/current/service_container/definitions.html 10
  11. Syntheticservices In some applications, you may need to inject a

    class instance as service, instead of configuring the container to create a new instance. https://symfony.com/doc/current/service_container/synthetic_services.html 11
  12. Container & Container Builder The ContainerBuilder is an object that

    helps you build Symfony’s service container by configuring it, adding some definitions, creating services etc. Container is a dependency injection container. (from class Description) https://medium.com/manomano-tech/diving-into-symfonys-dependencyinjection-part-1- first-steps-with-the-container-2fad0593c052 12
  13. Compiler Passes Tags Compiler Passes are classes that process the

    container to manipulate existing service definitions. Service tags are mechanism to flag services that require special processing. 13
  14. Compiler (Compiling) Dedicated object to process the container definition and

    apply all compiler passes. Its aim is to manipulate and optimize the container. 14
  15. Dumper (Dumping) Put the result of the Compiling step into

    a store. (PHP classes, Database, Redis etc.) 15
  16. How does it work in Drupal 8 ?

  17. 17 SIMPLIFIED WORKFLOW Visualize all objects

  18. DRUPAL CONTAINER 18 A dedicated container optimized for Drupal needs

    Based on a PHP array container definition dumped as a performance-optimized machine-readable format. Compatible with the default Symfony DIC è Implements « ContainerInterface » from SF DI Component è Use some useful « Exception » from SF DI Component
  19. 19

  20. DRUPAL CONTAINER BUILDER 20 A dedicated container builder for Drupal

    needs Compatible with the default Symfony DI ContainerBuilder è Extends « ContainerBuilder » from SF DI Component è Handle specific rules for Drupal 8 è Disable resources tracking è Check strtolower on service ID (set, register, setParamater) è …
  21. 21

  22. PHP ARRAY DUMPER 22 Like YML, but in pure PHP

    (Human format for readibility) Services are FLAT PHP ARRAY (Human readable format)
  23. OPTIMIZED PHP ARRAY DUMPER 23 For performances ! Services are

    SERIALIZED (Machine format)
  24. DI PROVIDED DUMPERS 24 For differents reasons…

  25. SEQUENCES 25 Steps to get the service container è Drupal

    boot() method is called from the DrupalKernel() class è Boot needs to initialize the Container with initializeContainer() è Kernel try to get the DIC if the container is injected via setContainer() è If there is no modules updates and if the container doesn’t need to be rebuilt, the Kernel gets the container definition from the cache with getCachedContainerDefinition() è If no Container is available and there is no cache Container Definition, the Kernel needs to compile the Container with compileContainer() and gets the Container Definition with the correct Dumper (default is OptimizedPhpArrayDumper)
  26. SEQUENCES 26 Steps to get the service container è Services

    Provider are collected, base parameters are set, namespaces are registered, base synthetics services are registered (class_loader, kernel and service_container) and Yaml files are loaded. è If a new container definition is created, the Kernel needs to create a new Container from container definition è Syntethic services are attached to the container with attachSynthetic() è Container is set on Drupal Core class with \Drupal::setContainer($this->container) è Final container is returned
  27. Altering DIC is easy !

  28. DRUPAL SERVICE PROVIDER 28 Interact with the container on «

    compile » time Module needs to provide a ServiceProvider {ModuleName}ServiceProvider.php IMPLEMENTS EXTENDS OR
  29. DRUPAL SERVICE PROVIDER 29 Interact with the container on «

    compile » time
  30. DEFAULT BOOTSTRAP CONTAINER DEFINITION 30 You can modify the default

    bootstrap with ease ! è Update settings « bootstrap_container_definition » è Extends the DrupalKernel
  31. The bad side…

  32. Differences with Symfony 32 Some differences… No Expression Language component

    : parameter() & service() No Drush command to debug container like Symfony
  33. Differences with Symfony 33 Some differences… Service Collector instead of

    TaggedIteratorArgument Drupal DI is ALWAYS behind Symfony DI (mecanical effect) è Dumper isn’t up to date (escape for % sign by ex.) è Code duplication isn’t up to date (YamlFileLoader, ContainerBuilder methods …) Drupal doesn’t use the full Symfony Component but implements Interface That’s why it is only « compatible » with SF Components Services are always public !
  34. Conclusion

  35. HELP US ! 35 Everybody are welcome ;) https://www.github.com/ekino/drupal-debug

  36. Thank’s for your attention Some questions ?