Commit b1c684b8 authored by alexpott's avatar alexpott

Issue #1988508 by katbailey: Stop pretending we support Symfony bundles when...

Issue #1988508 by katbailey: Stop pretending we support Symfony bundles when we really just have service providers.
parent 77947830
......@@ -1889,8 +1889,7 @@ function drupal_handle_request($test_only = FALSE) {
exit;
}
// @todo Figure out how best to handle the Kernel constructor parameters.
$kernel = new DrupalKernel('prod', FALSE, drupal_classloader(), !$test_only);
$kernel = new DrupalKernel('prod', drupal_classloader(), !$test_only);
// @todo Remove this once everything in the bootstrap has been
// converted to services in the DIC.
......@@ -2026,7 +2025,7 @@ function _drupal_bootstrap_kernel() {
// Normally, index.php puts a container in drupal_container() by creating a
// kernel. If there is no container yet, create one.
if (!drupal_container()) {
$kernel = new DrupalKernel('prod', FALSE, drupal_classloader());
$kernel = new DrupalKernel('prod', drupal_classloader());
$kernel->boot();
}
}
......
......@@ -4,14 +4,14 @@
use Drupal\Core\Config\FileStorage;
use Drupal\Core\DrupalKernel;
use Drupal\Core\CoreBundle;
use Drupal\Core\CoreServiceProvider;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Install\TaskException;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\StringTranslation\Translator\FileTranslation;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
......@@ -354,7 +354,7 @@ function install_begin_request(&$install_state) {
// @see drupal_install_config_directories()
// @see install_settings_form_submit()
if ($install_state['settings_verified']) {
$kernel = new DrupalKernel('install', FALSE, drupal_classloader(), FALSE);
$kernel = new DrupalKernel('install', drupal_classloader(), FALSE);
$kernel->boot();
$container = $kernel->getContainer();
// Add the file translation service to the container.
......@@ -426,7 +426,7 @@ function install_begin_request(&$install_state) {
$conf['keyvalue_expirable_default'] = 'keyvalue.expirable.null';
// Register Twig template engine for use during install.
CoreBundle::registerTwig($container);
CoreServiceProvider::registerTwig($container);
$container->register('url_generator', 'Drupal\Core\Routing\NullGenerator');
......
......@@ -619,7 +619,7 @@ function drupal_install_system() {
if (!drupal_container()->has('kernel')) {
// Immediately boot a kernel to have real services ready.
$kernel = new DrupalKernel('install', FALSE, drupal_classloader(), FALSE);
$kernel = new DrupalKernel('install', drupal_classloader(), FALSE);
$kernel->boot();
}
......
......@@ -103,10 +103,9 @@ function update_prepare_d8_bootstrap() {
$settings['cache']['default'] = 'cache.backend.memory';
new Settings($settings);
// Enable UpdateBundle service overrides. While the container_bundles array
// does not need a key, let's use so it can be removed once the upgrade are
// finished. @see update_flush_all_caches()
$GLOBALS['conf']['container_bundles']['UpdateBundle'] = 'Drupal\Core\DependencyInjection\UpdateBundle';
// Enable UpdateServiceProvider service overrides.
// @see update_flush_all_caches()
$GLOBALS['conf']['container_service_providers']['UpdateServiceProvider'] = 'Drupal\Core\DependencyInjection\UpdateServiceProvider';
// Check whether settings.php needs to be rewritten.
$settings_exist = !empty($GLOBALS['config_directories']);
......@@ -117,7 +116,7 @@ function update_prepare_d8_bootstrap() {
// Bootstrap the kernel.
// Do not attempt to dump and write it.
$kernel = new DrupalKernel('update', FALSE, drupal_classloader(), FALSE);
$kernel = new DrupalKernel('update', drupal_classloader(), FALSE);
$kernel->boot();
// If any of the required settings needs to be written, then settings.php
......@@ -440,7 +439,7 @@ function update_prepare_d8_bootstrap() {
$settings = settings()->getAll();
unset($settings['cache']['default']);
new Settings($settings);
$kernel = new DrupalKernel('update', FALSE, drupal_classloader(), FALSE);
$kernel = new DrupalKernel('update', drupal_classloader(), FALSE);
$kernel->boot();
}
......
......@@ -19,8 +19,8 @@
*
* The container is built by the kernel and passed in to this class which stores
* it statically. The container always contains the services from
* \Drupal\Core\CoreBundle, the bundles of enabled modules and any other bundles
* defined in $GLOBALS['conf']['container_bundles'].
* \Drupal\Core\CoreServiceProvider, the service providers of enabled modules and any other
* service providers defined in $GLOBALS['conf']['container_service_providers'].
*
* This class exists only to support legacy code that cannot be dependency
* injected. If your code needs it, consider refactoring it to be object
......
......@@ -2,12 +2,15 @@
/**
* @file
* Definition of Drupal\Core\CoreBundle.
* Definition of Drupal\Core\CoreServiceProvider.
*/
namespace Drupal\Core;
use Drupal\Core\Cache\ListCacheBinsPass;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
......@@ -18,16 +21,14 @@
use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterStringTranslatorsPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterBreadcrumbBuilderPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
/**
* Bundle class for mandatory core services.
* ServiceProvider class for mandatory core services.
*
* This is where Drupal core registers all of its compiler passes.
* The service definitions themselves are in core/core.services.yml with a
......@@ -36,12 +37,12 @@
* Modules wishing to register services to the container should use
* modulename.services.yml in their respective directories.
*/
class CoreBundle extends Bundle {
class CoreServiceProvider implements ServiceProviderInterface {
/**
* Implements \Symfony\Component\HttpKernel\Bundle\BundleInterface::build().
* {@inheritdoc}
*/
public function build(ContainerBuilder $container) {
public function register(ContainerBuilder $container) {
// The 'request' scope and service enable services to depend on the Request
// object and get reconstructed when the request object changes (e.g.,
// during a subrequest).
......@@ -67,6 +68,9 @@ public function build(ContainerBuilder $container) {
// Add the compiler pass that will process the tagged breadcrumb builder
// services.
$container->addCompilerPass(new RegisterBreadcrumbBuilderPass());
// Add the compiler pass that lets service providers modify existing
// service definitions.
$container->addCompilerPass(new ModifyServiceDefinitionsPass());
}
/**
......
<?php
/**
* @file
* Contains Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass.
*/
namespace Drupal\Core\DependencyInjection\Compiler;
use Drupal\Core\DrupalKernelInterface;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Passes the container to the alter() method of all service providers.
*/
class ModifyServiceDefinitionsPass implements CompilerPassInterface {
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
if (!$container->has('kernel')) {
return;
}
$kernel = $container->get('kernel');
if (!($kernel instanceof DrupalKernelInterface)) {
return;
}
$providers = $kernel->getServiceProviders();
foreach ($providers as $provider) {
if ($provider instanceof ServiceModifierInterface) {
$provider->alter($container);
}
}
}
}
<?php
namespace Drupal\Core\DependencyInjection;
/**
* Interface that service providers can implement to modify services.
*/
interface ServiceModifierInterface {
/**
* Modifies existing service definitions.
*
* @param ContainerBuilder $container
* The ContainerBuilder whose service definitions can be altered.
*/
public function alter(ContainerBuilder $container);
}
<?php
namespace Drupal\Core\DependencyInjection;
/**
* Interface that all service providers must implement.
*/
interface ServiceProviderInterface {
/**
* Registers services to the container.
*
* @param ContainerBuilder $container
* The ContainerBuilder to register services to.
*/
public function register(ContainerBuilder $container);
}
......@@ -2,27 +2,27 @@
/**
* @file
* Contains \Drupal\Core\DependencyInjection\UpdateBundle.
* Contains \Drupal\Core\DependencyInjection\UpdateServiceProvider.
*/
namespace Drupal\Core\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder as SymfonyContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
/**
* Bundle class for update.php service overrides.
* ServiceProvider class for update.php service overrides.
*
* This bundle is manually added by update.php via $conf['container_bundles']
* This class is manually added by update.php via $conf['container_service_providers']
* and required to prevent various services from trying to retrieve data from
* storages that do not exist yet.
*/
class UpdateBundle extends Bundle {
class UpdateServiceProvider implements ServiceProviderInterface {
/**
* Implements \Symfony\Component\HttpKernel\Bundle\BundleInterface::build().
* {@inheritdoc}
*/
public function build(SymfonyContainerBuilder $container) {
public function register(ContainerBuilder $container) {
// Disable the Lock service.
$container
->register('lock', 'Drupal\Core\Lock\NullLockBackend');
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
namespace Drupal\Core;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* The interface for DrupalKernel, the core of Drupal.
......@@ -15,7 +15,40 @@
* This interface extends Symfony's KernelInterface and adds methods for
* responding to modules being enabled or disabled during its lifetime.
*/
interface DrupalKernelInterface extends KernelInterface {
interface DrupalKernelInterface extends HttpKernelInterface, \Serializable {
/**
* Boots the current kernel.
*/
public function boot();
/**
* Shuts down the kernel.
*/
public function shutdown();
/**
* Discovers available serviceProviders.
*
* @return array
* The available serviceProviders.
*/
public function discoverServiceProviders();
/**
* Returns all registered service providers.
*
* @return array
* An associative array of ServiceProvider objects, keyed by name.
*/
public function getServiceProviders();
/**
* Gets the current container.
*
* @return ContainerInterface A ContainerInterface instance
*/
public function getContainer();
/**
* Updates the kernel's list of modules to the new list.
......
......@@ -81,7 +81,7 @@ class ModuleHandler implements ModuleHandlerInterface {
* %container.modules% parameter being set up by DrupalKernel.
*
* @see \Drupal\Core\DrupalKernel
* @see \Drupal\Core\CoreBundle
* @see \Drupal\Core\CoreServiceProvider
*/
public function __construct(array $module_list = array()) {
$this->moduleList = $module_list;
......
......@@ -6,7 +6,7 @@
*
* This provides a Twig extension that registers various Drupal specific extensions to Twig.
*
* @see \Drupal\Core\CoreBundle
* @see \Drupal\Core\CoreServiceProvider
*/
namespace Drupal\Core\Template;
......@@ -14,7 +14,7 @@
/**
* A class for providing Twig extensions (specific Twig_NodeVisitors, filters and functions).
*
* @see \Drupal\Core\CoreBundle
* @see \Drupal\Core\CoreServiceProvider
*/
class TwigExtension extends \Twig_Extension {
public function getFunctions() {
......
......@@ -2,23 +2,31 @@
/**
* @file
* Contains \Drupal\language_test\LanguageTestBundle.
* Contains \Drupal\language_test\LanguageTestServiceProvider.
*/
namespace Drupal\language_test;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
/**
* Defines the LanguageTest bundle.
* Defines the LanguageTest service provider.
*/
class LanguageTestBundle extends Bundle {
class LanguageTestServiceProvider implements ServiceProviderInterface, ServiceModifierInterface {
/**
* Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
* {@inheritdoc}
*/
public function build(ContainerBuilder $container) {
public function register(ContainerBuilder $container) {
}
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
// Overrides language_manager class to test domain language negotiation.
$definition = $container->getDefinition('language_manager');
$definition->setClass('Drupal\language_test\LanguageTestManager');
......
......@@ -2,23 +2,23 @@
/**
* @file
* Contains \Drupal\serialization\SerializationBundle.
* Contains \Drupal\serialization\SerializationServiceProvider.
*/
namespace Drupal\serialization;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
/**
* Serialization dependency injection container.
*/
class SerializationBundle extends Bundle {
class SerializationServiceProvider implements ServiceProviderInterface {
/**
* Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
* {@inheritdoc}
*/
public function build(ContainerBuilder $container) {
public function register(ContainerBuilder $container) {
// Add a compiler pass for adding Normalizers and Encoders to Serializer.
$container->addCompilerPass(new RegisterSerializationClassesCompilerPass());
// Add a compiler pass for adding concrete Resolvers to chain Resolver.
......
......@@ -90,7 +90,7 @@ protected function setUp() {
// Build a minimal, partially mocked environment for unit tests.
$this->containerBuild(drupal_container());
// Make sure it survives kernel rebuilds.
$GLOBALS['conf']['container_bundles'][] = 'Drupal\simpletest\TestBundle';
$GLOBALS['conf']['container_service_providers']['TestServiceProvider'] = 'Drupal\simpletest\TestServiceProvider';
\Drupal::state()->set('system.module.files', $this->moduleFiles);
\Drupal::state()->set('system.theme.files', $this->themeFiles);
......@@ -98,7 +98,7 @@ protected function setUp() {
// Bootstrap the kernel.
// No need to dump it; this test runs in-memory.
$this->kernel = new DrupalKernel('unit_testing', TRUE, drupal_classloader(), FALSE);
$this->kernel = new DrupalKernel('unit_testing', drupal_classloader(), FALSE);
$this->kernel->boot();
// Collect and set a fixed module list.
......
......@@ -698,7 +698,7 @@ protected function verbose($message) {
* methods during debugging.
*/
public function run(array $methods = array()) {
TestBundle::$currentTest = $this;
TestServiceProvider::$currentTest = $this;
$simpletest_config = config('simpletest.settings');
$class = get_class($this);
......@@ -770,7 +770,7 @@ public function run(array $methods = array()) {
}
}
}
TestBundle::$currentTest = NULL;
TestServiceProvider::$currentTest = NULL;
// Clear out the error messages and restore error handler.
drupal_get_messages();
restore_error_handler();
......@@ -993,7 +993,7 @@ protected function prepareConfigDirectories() {
* @see TestBase::tearDown()
*/
protected function rebuildContainer() {
$this->kernel = new DrupalKernel('testing', FALSE, drupal_classloader(), FALSE);
$this->kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
$this->kernel->boot();
// DrupalKernel replaces the container in drupal_container() with a
// different object, so we need to replace the instance on this test class.
......
......@@ -2,10 +2,10 @@
namespace Drupal\simpletest;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
class TestBundle extends Bundle {
class TestServiceProvider implements ServiceProviderInterface {
/**
* @var \Drupal\simpletest\TestBase;
......@@ -13,12 +13,11 @@ class TestBundle extends Bundle {
public static $currentTest;
/**
* Implements \Symfony\Component\HttpKernel\Bundle\BundleInterface::build().
* {@inheritdoc}
*/
function build(ContainerBuilder $container) {
function register(ContainerBuilder $container) {
if (static::$currentTest && method_exists(static::$currentTest, 'containerBuild')) {
static::$currentTest->containerBuild($container);
}
}
}
......@@ -201,7 +201,7 @@ function hook_language_fallback_candidates_alter(array &$fallback_candidates) {
* hook_transliteration_overrides_alter() to provide further language-specific
* overrides (including providing transliteration for Unicode characters that
* are longer than 4 bytes). Modules can also completely override the
* transliteration classes in \Drupal\Core\CoreBundle.
* transliteration classes in \Drupal\Core\CoreServiceProvider.
*/
/**
......
<?php
/**
* @file
* Definition of Drupal\system\Tests\Bundle\BundleTest.
*/
namespace Drupal\system\Tests\Bundle;
use Drupal\simpletest\WebTestBase;
/**
* Tests bundle registration to the DIC.
*/
class BundleTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('bundle_test');
public static function getInfo() {
return array(
'name' => 'Bundle Registration',
'description' => 'Tests bundle registration to the DIC.',
'group' => 'Bundle',
);
}
/**
* Tests that services provided by module bundles get registered to the DIC.
*/
function testBundleRegistration() {
$this->assertTrue(drupal_container()->getDefinition('file.usage')->getClass() == 'Drupal\\bundle_test\\TestFileUsage', 'Class has been changed');
$this->assertTrue(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service has been registered to the DIC');
// The event subscriber method in the test class calls drupal_set_message with
// a message saying it has fired. This will fire on every page request so it
// should show up on the front page.
$this->drupalGet('');
$this->assertText(t('The bundle_test event subscriber fired!'), 'The bundle_test event subscriber fired');
}
/**
* Tests that the DIC keeps up with module enable/disable in the same request.
*/
function testBundleRegistrationDynamic() {
// Disable the module and ensure the bundle's service is not registered.
module_disable(array('bundle_test'));
$this->assertFalse(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service does not exist in the DIC.');
// Enable the module and ensure the bundle's service is registered.
module_enable(array('bundle_test'));
$this->assertTrue(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service exists in the DIC.');
}
}
......@@ -49,12 +49,12 @@ function testCompileDIC() {
'system' => 'system',
'user' => 'user',
);
$kernel = new DrupalKernel('testing', FALSE, $classloader);
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
// Instantiate it a second time and we should get the compiled Container
// class.
$kernel = new DrupalKernel('testing', FALSE, $classloader);
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
......@@ -68,7 +68,7 @@ function testCompileDIC() {
// environment.
global $conf;
$conf['php_storage']['service_container']['class'] = 'Drupal\Component\PhpStorage\FileReadOnlyStorage';
$kernel = new DrupalKernel('testing', FALSE, $classloader);
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
......@@ -86,17 +86,17 @@ function testCompileDIC() {
// is functioning correctly, i.e. we get a brand new ContainerBuilder
// which has the required new services, after changing the list of enabled
// modules.
$this->assertFalse($container->has('bundle_test_class'));
$this->assertFalse($container->has('service_provider_test_class'));
// Add another module so that we can test that the new module's bundle is
// registered to the new container.
$module_enabled['bundle_test'] = 'bundle_test';
$kernel = new DrupalKernel('testing', FALSE, $classloader);
$module_enabled['service_provider_test'] = 'service_provider_test';
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
// Instantiate it a second time and we should still get a ContainerBuilder
// class because we are using the read-only PHP storage.
$kernel = new DrupalKernel('testing', FALSE, $classloader);
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
......@@ -104,14 +104,14 @@ function testCompileDIC() {
$is_container_builder = $refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_container_builder);
// Assert that the new module's bundle was registered to the new container.
$this->assertTrue($container->has('bundle_test_class'));
$this->assertTrue($container->has('service_provider_test_class'));
// Test that our synthetic services are there.
$classloader = $container->get('class_loader');
$refClass = new ReflectionClass($classloader);
$this->assertTrue($refClass->hasMethod('loadClass'), 'Container has a classloader');
// Check that the location of the new module is registered.
$modules = $container->getParameter('container.modules');
$this->assertEqual($modules['bundle_test'], drupal_get_filename('module', 'bundle_test'));
$this->assertEqual($modules['service_provider_test'], drupal_get_filename('module', 'service_provider_test'));
}
/**
......@@ -119,7 +119,7 @@ function testCompileDIC() {
*/
public function testSerialization() {
$classloader = drupal_classloader();
$kernel = new DrupalKernel('testing', FALSE, $classloader);
$kernel = new DrupalKernel('testing', $classloader);
$string = serialize($kernel);
$unserialized_kernel = unserialize($string);
......
......@@ -29,16 +29,16 @@ public static function getInfo() {
*/
public function testDestructionUsed() {
// Enable the test module to add it to the container.
$this->enableModules(array('bundle_test'));
$this->enableModules(array('service_provider_test'));
// The service has not been destructed yet.
$this->assertNull(\Drupal::state()->get('bundle_test.destructed'));
$this->assertNull(\Drupal::state()->get('service_provider_test.destructed'));
// Call the class and then terminate the kernel
$this->container->get('bundle_test_class');
$this->container->get('service_provider_test_class');
$response = new Response();
$this->container->get('kernel')->terminate($this->container->get('request'), $response);
$this->assertTrue(\Drupal::state()->get('bundle_test.destructed'));
$this->assertTrue(\Drupal::state()->get('service_provider_test.destructed'));
}
/**
......@@ -46,15 +46,15 @@ public function testDestructionUsed() {
*/
public function testDestructionUnused() {
// Enable the test module to add it to the container.
$this->enableModules(array('bundle_test'));
$this->enableModules(array('service_provider_test'));
// The service has not been destructed yet.
$this->assertNull(\Drupal::state()->get('bundle_test.destructed'));
$this->assertNull(\Drupal::state()->get('service_provider_test.destructed'));
// Terminate the kernel. The test class has not been called, so it should not
// be destructed.
$response = new Response();
$this->container->get('kernel')->terminate($this->container->get('request'), $response);
$this->assertNull(\Drupal::state()->get('bundle_test.destructed'));
$this->assertNull(\Drupal::state()->get('service_provider_test.destructed'));
}
}
<?php
/**
* @file
* Definition of Drupal\system\Tests\ServiceProvider\ServiceProviderTest.
*/
namespace Drupal\system\Tests\ServiceProvider;
use Drupal\simpletest\WebTestBase;
/**