diff --git a/core/core.services.yml b/core/core.services.yml index 9f5d6fc..a39c5ae 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -442,6 +442,8 @@ services: class: SplString factory_service: 'app.root.factory' factory_method: 'get' + tags: + - { name: SplString, tag: 'non_class'} app.root.factory: class: Drupal\Core\AppRootFactory arguments: ['@kernel'] diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index 82fa4c4..6f43415 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -12,6 +12,7 @@ use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass; use Drupal\Core\DependencyInjection\Compiler\RegisterLazyRouteEnhancers; use Drupal\Core\DependencyInjection\Compiler\RegisterLazyRouteFilters; +use Drupal\Core\DependencyInjection\Compiler\DependencySerializationTraitPass; use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass; use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass; use Drupal\Core\DependencyInjection\ServiceProviderInterface; @@ -84,6 +85,8 @@ public function register(ContainerBuilder $container) { // Register plugin managers. $container->addCompilerPass(new PluginManagerPass()); + + $container->addCompilerPass(new DependencySerializationTraitPass()); } /** diff --git a/core/lib/Drupal/Core/DependencyInjection/Container.php b/core/lib/Drupal/Core/DependencyInjection/Container.php index 0d4c972..4e28d54 100644 --- a/core/lib/Drupal/Core/DependencyInjection/Container.php +++ b/core/lib/Drupal/Core/DependencyInjection/Container.php @@ -17,14 +17,13 @@ class Container extends SymfonyContainer { /** * {@inheritdoc} */ - public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) { - $service = parent::get($id, $invalidBehavior); - // Some services are called but do not exist, so the parent returns nothing. - if (is_object($service)) { - $service->_serviceId = $id; - } + public function set($id, $service, $scope = SymfonyContainer::SCOPE_CONTAINER) { + parent::set($id, $service, $scope); - return $service; + // Ensure that the _serviceId property is set on synthetic services as well. + if (isset($this->services[$id]) && is_object($this->services[$id]) && !isset($this->services[$id]->_serviceId)) { + $this->services[$id]->_serviceId = $id; + } } /** diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php index ba29a66..16bf0ad 100644 --- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php +++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php @@ -30,19 +30,6 @@ public function __construct(ParameterBagInterface $parameterBag = NULL) { } /** - * {@inheritdoc} - */ - public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) { - $service = parent::get($id, $invalidBehavior); - // Some services are called but do not exist, so the parent returns nothing. - if (is_object($service)) { - $service->_serviceId = $id; - } - - return $service; - } - - /** * Overrides Symfony\Component\DependencyInjection\ContainerBuilder::set(). * * Drupal's container builder can be used at runtime after compilation, so we @@ -59,6 +46,11 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER) { if ($this->hasDefinition($id) && ($definition = $this->getDefinition($id)) && $definition->isSynchronized()) { $this->synchronize($id); } + + // Ensure that the _serviceId property is set on synthetic services as well. + if (isset($this->services[$id]) && is_object($this->services[$id]) && !isset($this->services[$id]->_serviceId)) { + $this->services[$id]->_serviceId = $id; + } } /** diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php index a3f4114..f2537c8 100644 --- a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php @@ -10,6 +10,7 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Tests\UnitTestCase; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass; require_once __DIR__ . '../../../../../../vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php'; @@ -50,7 +51,18 @@ public function testGet() { $result = $container->get('bar'); $this->assertTrue($result instanceof \BarClass); - $this->assertEquals('bar', $result->_serviceId); + } + + /** + * Tests the set() method. + * + * @covers ::set + */ + public function testSet() { + $container = new ContainerBuilder(); + $class = new BarClass(); + $container->set('bar', $class); + $this->assertEquals('bar', $class->_serviceId); } } diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php index e892f22..5c73281 100644 --- a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php +++ b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php @@ -9,6 +9,7 @@ use Drupal\Core\DependencyInjection\Container; use Drupal\Tests\UnitTestCase; +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass; /** * @coversDefaultClass \Drupal\Core\DependencyInjection\Container @@ -31,18 +32,23 @@ protected function setUp() { } /** - * Tests the get method. + * Tests serialization. * - * @see \Drupal\Core\DependencyInjection\Container::get() + * @expectedException \PHPUnit_Framework_Error */ - public function testGet() { - $service = new \stdClass(); - $service->key = 'value'; - - $this->container->set('test_service', $service); - $result = $this->container->get('test_service'); - $this->assertSame($service, $result); - $this->assertEquals('test_service', $result->_serviceId); + public function testSerialize() { + serialize($this->container); + } + + /** + * Tests the set() method. + * + * @covers ::set + */ + public function testSet() { + $class = new BarClass(); + $this->container->set('bar', $class); + $this->assertEquals('bar', $class->_serviceId); } }