Drupal Symfony Inject

black drupal logo - http://drufony.github.io/

References

https://www.drupal.org/node/2133171
https://drupal.org/project/drupal_symfony_inject

https://github.com/legovaer/di-example

http://symfony.com/doc/current/components/dependency_injection/introduction.html

https://johnmunsch.com/tag/dependency-injection/

https://github.com/Ocramius/ProxyManager

https://www.drupal.org/project/composer_manager

http://www.oracle.com/technetwork/testcontent/opensso-091890.html

https://www.forgerock.com/platform/access-management/

https://getcomposer.org/doc/

@legovaer

  • Validators Module
  • User Dashboard Module
  • Drupal Symfony Inject Module
  • Scheduler Module (Port to D8)
  • Drupal CI

Drupal using Symfony's Dependency Injection

Drupal

Symfony

Inject

The DependencyInjection component allows you to standardize and centralize the way objects are constructed in your application.

The Easiest Way

When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get Mommy or Daddy doesn't want you to have. You might even be looking for something we don't even have or which has expired.

What you should be doing is stating a need, "I need something to drink with lunch." and then we will make sure you have something when you sit down to eat.

Answer by John Munsch -- http://stackoverflow.com/questions/1638919/how-to-explain-dependency-injection-to-a-5-year-old/1638961#1368961

 

Can I have a Belgian beer please?

 

Drupal 7

Drupal Symfony Inject Module

Drupal Cache API

Composer Manager Module

Ocramius/ProxyManager

Symfony Dependency Injection

INSTALLATION

Drupal Symfony Inject Module

Drupal Cache API

Ocramius/ProxyManager

Symfony Dependency Injection

EXECUTION / DISCOVERY

HOOKS

  1. hook_symfony_yaml_config()

  2. hook_symfony_yaml_config_params()

  3. hook_symfony_yaml_config_params_alter()

  4. hook_symfony_container_builder_alter()

  5. hook_namespace_register()

Drupal Symfony Inject Module

Drupal 8

services.yml

parameters:
  http.response.debug_cacheability_headers: false


services:
  finish_response_subscriber:
    class: Drupal\Core\EventSubscriber\FinishResponseSubscriber
    tags:
      - { name: event_subscriber }
    arguments: ['@language_manager', '%http.response.debug_cacheability_headers%']
  language_manager:
    class: Drupal\Core\Language\LanguageManager
    arguments: ['@language.default']

services.yml

parameters:
  factory.keyvalue:
    default: keyvalue.database

services:
  settings:
    class: Drupal\Core\Site\Settings
    factory: Drupal\Core\Site\Settings::getInstance
  keyvalue:
    class: Drupal\Core\KeyValueStore\KeyValueFactory
    arguments: ['@service_container', '%factory.keyvalue%']
  cache_factory:
    class: Drupal\Core\Cache\CacheFactory
    arguments: ['@settings', '%cache_default_bin_backends%']
    calls:
      - [setContainer, ['@service_container']]
  keyvalue.database:
    class: Drupal\Core\KeyValueStore\KeyValueDatabaseFactory
    arguments: ['@serialization.phpserialize', '@database']

ServiceProvider

class LanguageServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container) {
    // The following services are needed only on multilingual sites.
    if ($this->isMultilingual()) {
      $container->register('language_request_subscriber', 'Drupal\language\EventSubscriber\LanguageRequestSubscriber')
        ->addTag('event_subscriber')
        ->addArgument(new Reference('language_manager'))
        ->addArgument(new Reference('language_negotiator'))
        ->addArgument(new Reference('string_translation'))
        ->addArgument(new Reference('current_user'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container) {
    // For monolingual sites, we explicitly set the default language for the
    // language config override service as there is no language negotiation.
    if (!$this->isMultilingual()) {
      $container->getDefinition('language.config_factory_override')
        ->addMethodCall('setLanguageFromDefault', array(new Reference('language.default')));
    }

  }

ServiceProvider

<?php

class CoreServiceProvider implements ServiceProviderInterface {

  public function register(ContainerBuilder $container) {
    $container->addCompilerPass(new ListCacheBinsPass());
  }

}

CompilerPass

<?php

/**
 * Adds cache_bins parameter to the container.
 */
class ListCacheBinsPass implements CompilerPassInterface {

  /**
   * Implements CompilerPassInterface::process().
   *
   * Collects the cache bins into the cache_bins parameter.
   */
  public function process(ContainerBuilder $container) {
    $cache_bins = array();
    $cache_default_bin_backends = array();
    foreach ($container->findTaggedServiceIds('cache.bin') as $id => $attributes) {
      $bin = substr($id, strpos($id, '.') + 1);
      $cache_bins[$id] = $bin;
      if (isset($attributes[0]['default_backend'])) {
        $cache_default_bin_backends[$bin] = $attributes[0]['default_backend'];
      }
    }
    $container->setParameter('cache_bins', $cache_bins);
    $container->setParameter('cache_default_bin_backends', $cache_default_bin_backends);
  }

}

Summary

Services.yml

Service Provider

Service Tags

CompilerPass

An example in the wild

Switch between OpenSSO / OpenAM

Multiple codebases, minimize code effort

Low risk on regression

Drupal Website A

Drupal Website B

vendor/opensso_client

opensso_login/services.yml

opensso_login/opensso_login.module

Implements hook_symfony_yaml_config_params()

vendor/legovaer/opensso/Client.php

Thanks!

deck

By Levi Govaerts