Change record status: 
Project: 
Introduced in branch: 
10.2.x
Introduced in version: 
10.2.0
Description: 

Symfony services can have arrays as arguments that contain services that are wrapped in a memoizing closure, this is now also supported by the Drupal implementation.

This feature wraps the injected service into a closure allowing it to be lazily loaded when and if needed. This is useful if the service being injected is a bit heavy to instantiate or is used only in certain cases. The service is instantiated the first time the closure is called, while all subsequent calls return the same instance, unless the service is not shared:

// modules/custom_module/src/MyService.php

namespace Drupal\custom_module;

use Drupal\Core\Mail\MailManagerInterface;

class MyService {

  public function __construct(
    protected \Closure $mailManager,
  ) {}

  public function doSomething(): void {
    // ...
    $this->getMailManager()->mail('custom_module', 'my_mail', $recipient, $langcode, $params);
  }

  protected function getMailManager(): MailManagerInterface {
    return ($this->mailManager)();
  }

}

See also Services can now define service closures as arguments in services.yml files.

Impacts: 
Module developers