Service declaration providers must now be explicitly registered in a module's services.yml file and tagged with service_provider.
There are no restrictions on the service provider's class name or namespace. Multiple service can be registered, too.
Previously, a services provider class was implicitly detected, but its class name had to be formed from the camel case version of the module's name, e.g., for a module my_module, the class has to be named MyModuleServiceProvider and be in the module's top-level namespace.
Before
File: my_module/MyModuleServiceProvider.php
class MyModuleServiceProvider implements ServiceProviderInterface { ... }
After
File: my_module.services.yml
services:
my_module.service_provider:
class: Drupal\my_module\AnyName
tags:
- { name: service_provider }
File: my_module/src/AnyName.php
class AnyName implements ServiceProviderInterface { ... }
Note: injecting dependencies should only be done with great care as the container is still being built and many services do not work. However, this is not new as the methods got the container passed to them and the same restrictions apply. Instead of services, consider:
- Installed modules are the keys of
$container->getParameter('container.modules') - While the whole config subsystem is not available, config storage is, use
BootstrapConfigStorageFactory::get(), seeDrupal\language\LanguageServiceProvider::getDefaultLanguageValues()for an example. - Using
$settingsinsettings.phpandDrupal\Core\Site\Settings::get()is usually more adequate than config here.
Keeping the same name is possible, this allows maintaining a single codebase for Drupal before and after this change. In this case just add the service definition into the container, Drupal versions without this change won't do anything with it. Also do not inject anything into the service because older Drupals just do new ModuleServiceProvider.