You are here

class ContainerBuilder in Service Container 7.2

Same name in this branch
  1. 7.2 src/DependencyInjection/ContainerBuilder.php \Drupal\service_container\DependencyInjection\ContainerBuilder
  2. 7.2 lib/Drupal/Core/DependencyInjection/ContainerBuilder.php \Drupal\Core\DependencyInjection\ContainerBuilder
  3. 7.2 modules/providers/service_container_symfony/lib/Symfony/Component/DependencyInjection/ContainerBuilder.php \Symfony\Component\DependencyInjection\ContainerBuilder
Same name and namespace in other branches
  1. 7 src/DependencyInjection/ContainerBuilder.php \Drupal\service_container\DependencyInjection\ContainerBuilder

ContainerBuilder retrieves container definitions from service providers to build a Container.

Hierarchy

Expanded class hierarchy of ContainerBuilder

2 files declare their use of ContainerBuilder
CachedContainerBuilderTest.php in tests/src/DependencyInjection/CachedContainerBuilderTest.php
Contains \Drupal\Tests\service_container\DependencyInjection\CachedContainerBuilderTest
ContainerBuilderTest.php in tests/src/DependencyInjection/ContainerBuilderTest.php
Contains \Drupal\Tests\service_container\DependencyInjection\ContainerBuilderTest

File

src/DependencyInjection/ContainerBuilder.php, line 19
Contains \Drupal\service_container\DependencyInjection\ContainerBuilder

Namespace

Drupal\service_container\DependencyInjection
View source
class ContainerBuilder implements ContainerBuilderInterface {

  /**
   * The plugin manager that provides the service definition providers.
   *
   * @var PluginManagerInterface
   */
  protected $serviceProviderManager;

  /**
   * The container class to instantiate.
   *
   * To override this, use a service called container and set a class
   * attribute.
   */
  protected $containerClass = '\\Drupal\\service_container\\DependencyInjection\\Container';

  /**
   * Constructs a ContainerBuilder object.
   *
   * @param PluginManagerInterface $service_provider_manager
   *   The service provider manager that provides the service providers,
   *   which define the services used in the container.
   */
  public function __construct(PluginManagerInterface $service_provider_manager) {
    $this->serviceProviderManager = $service_provider_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function getContainerDefinition() {
    $definitions = $this->serviceProviderManager
      ->getDefinitions();
    $container_definition = array();
    $service_providers = array();

    // Populate service providers.
    foreach ($definitions as $plugin_id => $definition) {
      $service_providers[$plugin_id] = $this->serviceProviderManager
        ->createInstance($plugin_id);
    }

    // Get container definition of each service provider and merge them.
    foreach ($definitions as $plugin_id => $definition) {
      $service_provider = $service_providers[$plugin_id];
      $container_definition = NestedArray::mergeDeep($container_definition, $service_provider
        ->getContainerDefinition());
    }
    $container_definition += array(
      'services' => array(),
      'parameters' => array(),
    );

    // @codeCoverageIgnore
    // Find and setup tags for container altering.
    $container_definition['tags'] = array();

    // Setup the tags structure.
    foreach ($container_definition['services'] as $service => $definition) {
      if (isset($definition['tags'])) {
        foreach ($definition['tags'] as $tag) {
          $tag_name = $tag['name'];
          unset($tag['name']);
          $container_definition['tags'][$tag_name][$service][] = $tag;
        }
      }
    }

    // Ensure container definition can be altered.
    foreach ($definitions as $plugin_id => $definition) {
      $service_provider = $service_providers[$plugin_id];
      $service_provider
        ->alterContainerDefinition($container_definition);
    }

    // Last give a chance for traditional modules to alter this.
    $this
      ->moduleAlter($container_definition);

    // Remove the tags again, not needed for the final build of the container.
    unset($container_definition['tags']);
    return $container_definition;
  }

  /**
   * {@inheritdoc}
   */
  public function compile() {
    $definition = $this
      ->getContainerDefinition();
    if (!empty($definition['services']['service_container']['class'])) {
      $this->containerClass = $definition['services']['service_container']['class'];
    }
    return new $this->containerClass($definition);
  }

  /**
   * Provides class based version of drupal_alter() to allow testing.
   *
   * This function must be mocked for unit tests.
   *
   * Note: Only the container builder needs this, other classes should
   *       use the ModuleHandler within the container.
   *
   * @param $container_definition
   *   The fully build container definition that can be altered by modules now.
   *
   * @codeCoverageIgnore
   */
  protected function moduleAlter(&$container_definition) {
    drupal_alter('service_container_container_build', $container_definition);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ContainerBuilder::$containerClass protected property The container class to instantiate.
ContainerBuilder::$serviceProviderManager protected property The plugin manager that provides the service definition providers.
ContainerBuilder::compile public function Compiles the container builder to a new container. Overrides ContainerBuilderInterface::compile
ContainerBuilder::getContainerDefinition public function Returns the fully build container definition. Overrides ContainerBuilderInterface::getContainerDefinition 1
ContainerBuilder::moduleAlter protected function Provides class based version of drupal_alter() to allow testing.
ContainerBuilder::__construct public function Constructs a ContainerBuilder object. 1