Autowire at discovery time.
Closes #3294266
Merge request reports
Activity
- Resolved by Stephen Mustgrave
- Resolved by Stephen Mustgrave
- Resolved by Dave Long
- Resolved by Stephen Mustgrave
- Resolved by Stephen Mustgrave
added 2 commits
added 2 commits
21 21 * The plugin ID. 22 22 * @param class-string|null $deriver 23 23 * (optional) The deriver class. 24 * @param bool $autowire 25 * (optional) Whether the plugin should be autowired. 24 26 */ 25 27 public function __construct( 26 28 public readonly string $id, 27 29 public readonly ?string $deriver = NULL, 30 public readonly bool $autowire = FALSE, 28 31 ) {} - Comment on lines 25 to 28
This would enforce projects to add the new attribute property to all plugins. A lot of changes. It would be good to allow projects to set a global flag and set all plugins to opt in:
27 public function __construct( 28 public readonly string $id, 29 public readonly ?string $deriver = NULL, 30 public readonly bool $autowire = FALSE, 31 ) {} 27 public function __construct( 28 public readonly string $id, 29 public readonly ?string $deriver = NULL, 30 public readonly bool $autowire = NULL, 31 ) { 32 $this->autowire = Settings::get('autowire_plugins', FALSE); 33 } Anyway, we need something that projects could turn ON/OFF globally.
Related: https://www.drupal.org/project/drupal/issues/3452304
I don't see how this can be done as a global setting, it's not up to the site owner to know or care if their plugins should all be autowired.
Each plugin type has to add the autowire property, but this is the only way of letting plugins individually opt in to autowiring, somewhat similar to how it is done in services.yml. New plugin managers/types could set this default to TRUE if they want, but we can't do that to existing plugins until they have all had chance to actually enable it manually.
added 2 commits
53 52 $this->routeMatch = $route_match; 54 53 } 55 54 56 /** 57 * {@inheritdoc} 58 */ 59 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { We can't actually delete this yet, in case a subclass is calling
parent::create()
. Does that mean we have to add a deprecation to everycreate()
method that we convert to autowiring, though?Edited by Dave Long
31 } 32 19 33 // If the plugin provides a factory method, pass the container to it. 20 if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) { 34 if (is_subclass_of($plugin_class, ContainerFactoryPluginInterface::class)) { 35 return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition); 36 } 37 38 // Backward compatibility for plugins that provide a factory method but 39 // the parent no longer implements the interface (because it is autowired). 40 if (method_exists($plugin_class, 'create')) { 41 // Additional checks are required to be sure we have a factory method. 42 // @see \Drupal\Tests\Core\Menu\MenuLinkMock::create() 43 $method = new \ReflectionMethod($plugin_class, 'create'); 44 if ($method->isStatic() && count($method->getParameters()) === 4) { 45 @trigger_error(sprintf('Implementing a factory method in %s without implementing %s is deprecated in drupal:11.2.0 and will be removed in drupal:12.0.0. Implement the interface or convert the plugin to use autowiring. See https://www.drupal.org/node/7654321', $plugin_class, ContainerFactoryPluginInterface::class), E_USER_DEPRECATED);