Change record status: 
Project: 
Introduced in branch: 
6.x
Introduced in version: 
6.x-alpha1
Description: 

From: https://www.drupal.org/core/d8-bc-policy#constructors

The constructor for a service object (one in the container), plugin, or controller is considered internal unless otherwise marked, and may change in a minor release. These are objects where developers are not expected to call the constructor directly in the first place. Constructors for value objects where a developer will be calling the constructor directly are excluded from this statement.

The Webform module's service objects, plugins, and controllers have been refactored to rely on the dependency injection container for adding new services instead of overriding the constructor.

For more information and background information, please read…

Example

Below is the before and after for this new approach applied to the Drupal\webform\Plugin\WebformHandler\EmailWebformHandler plugin.

Before

Look at the very scary and overwhelming EmailWebformHandler::__construct method with too many parameters.

namespace Drupal\webform\Plugin\WebformHandler;

class EmailWebformHandler extends WebformHandlerBase implements WebformHandlerMessageInterface {
  ...
  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, WebformSubmissionConditionsValidatorInterface $conditions_validator, AccountInterface $current_user, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, MailManagerInterface $mail_manager, WebformThemeManagerInterface $theme_manager, WebformTokenManagerInterface $token_manager, WebformElementManagerInterface $element_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $logger_factory, $config_factory, $entity_type_manager, $conditions_validator);
    $this->currentUser = $current_user;
    $this->moduleHandler = $module_handler;
    $this->languageManager = $language_manager;
    $this->mailManager = $mail_manager;
    $this->themeManager = $theme_manager;
    $this->tokenManager = $token_manager;
    $this->elementManager = $element_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('logger.factory'),
      $container->get('config.factory'),
      $container->get('entity_type.manager'),
      $container->get('webform_submission.conditions_validator'),
      $container->get('current_user'),
      $container->get('module_handler'),
      $container->get('language_manager'),
      $container->get('plugin.manager.mail'),
      $container->get('webform.theme_manager'),
      $container->get('webform.token_manager'),
      $container->get('plugin.manager.webform.element')
    );
  }
  ...
}

After

The new code is now much simpler, cleaner, and easier to read.

namespace Drupal\webform\Plugin\WebformHandler;

class EmailWebformHandler extends WebformHandlerBase implements WebformHandlerMessageInterface {
  ...
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    $instance->currentUser = $container->get('current_user');
    $instance->moduleHandler = $container->get('module_handler');
    $instance->languageManager = $container->get('language_manager');
    $instance->mailManager = $container->get('plugin.manager.mail');
    $instance->themeManager = $container->get('webform.theme_manager');
    $instance->tokenManager = $container->get('webform.token_manager');
    $instance->elementManager = $container->get('plugin.manager.webform.element');
    return $instance;
  }
  ...
}

Any contrib module or custom code that extends a Webform service object, plugin, or controller may be broken by this change and will need to be reworked to support this new implementation pattern. This new implementation pattern is backward compatible and will work with both Webform 5,x and 6.x releases.

Impacts: 
Site builders, administrators, editors
Module developers
Site templates, recipes and distribution developers

Comments

gaëlg’s picture

See https://www.drupal.org/project/drupal/issues/3030640 for why the same doesn't apply to core.