Drupal Service ID Collectors
Drupal Service ID Collectors
Since Drupal 8 we've had services. This also brought the concept of a service collector or tagged services. This allows services to be tagged with a specific tag, then a service collector can collect all services with the a given tag and use whichever service "applies".
As you could imagine loaded all of these tagged services when loading the service collector service can be a performance nightmare, which is why Drupal 8.4.0 brought us service ID collector functionality.
Tagging a service with the service_id_collector
tag will pass all services with a given tag as the last parameter in the constructor. This will be an array of service IDs ordered by the priority. You will then need to use the ClassResolver
service to lazily instantiate the collected service IDs.
my_module.services.ymlmy_module.negotiator:<br> class: \Drupal\my_module\MyModuleNegotiator<br> arguments: {'@class.resolver'}<br> tags:<br> - { name: service_id_collector, tag: my_module_negotiator }<br>my_module.negotiator.foo:<br> class:\Drupal\my_module\FooNegotiator<br> arguments: {'@entity_type.manager'}<br> tags:<br> - { name: my_module_negotiator, priority: 100 }<br>my_module.negotiator.bar:<br> class:\Drupal\my_module\BarNegotiator<br> arguments: {'@entity_type.manager'}<br> tags:<br> - { name: my_module_negotiator, priority: -100 }<br>my_module.negotiator.baz:<br> class:\Drupal\my_module\BazNegotiator<br> arguments: {'@entity_type.manager'}<br> tags:<br> - { name: my_module_negotiator, priority: 0 }
MyModuleNegotiator.php/**<br> * The negotiator for my module.<br> */<br>class MyModuleNegotiator {<br><br> /**<br> * The class resolver service.<br> *<br> * @var \Drupal\Core\DependencyInjection\ClassResolver<br> */<br> protected $classResolver;<br><br> /**<br> * The negotiator service IDs.<br> *<br> * @var array<br> */<br> protected $negotiatorServiceIds;
/**<br> * Constructs the negotiator.<br> *<br> * @param \Drupal\Core\DependencyInjection\ClassResolver $class_resolver
* The class resolver service.<br> * @param array $negotiator_service_ids<br> * The negotiator service IDs.<br> */
public function __construct(ClassResolverInterface $class_resolver, array $negotiator_service_ids) {<br> $this->classResolver = $class_resolver;<br> $this->negotiatorServiceIds = $negotiator_service_ids;<br> }
/**<br> * Run the negotiators.<br> */<br> public function runNegotiators() {<br> foreach ($this->negotiatorServiceIds as $negotiator_service_id) {<br> $negotiator = $this->classResolver->getInstanceFromDefinition($negotiator_service_id);<br> if ($negotiator->applies()) {<br> $negotiator->run();<br> }<br> }<br> }<br>}
timmillwood
Thu, 14/12/2017 - 09:29
Tags
drupal planet
drupal-planet
drupal8
Add new comment