Change record status: 
Project: 
Introduced in branch: 
11.3.x
Introduced in version: 
11.3.0
Description: 

Form callbacks such as validate or submit callbacks now support any callables that Drupal\Core\Utility\CallableResolver supports.

These callbacks can now live in services and will support dependency injection.

Note that the callback no longer needs to be static.

Before:

$form['#submit'][] = [FileFormHooks::class, 'settingsSubmit'];
...

public static function settingsSubmit(array &$form, FormStateInterface $form_state): void {

After:

$form['#submit'][] = static::class . ':settingsSubmit';
...

public function settingsSubmit(array &$form, FormStateInterface $form_state): void {

In this example, the callable string is Drupal\file\Hook\FileFormHooks:settingsSubmit where Drupal\file\Hook\FileFormHooks is a registered service name.

Note

It first checks if the service container is available and uses the callable resolver service to get the callable from the definition. Otherwise, it returns the definition as is.

⚠️ Warning
Using $this as a pointer for form callback [$this, 'someMethod'] is an antipattern and should be avoided as the form will be serialized.

Impacts: 
Module developers
Themers
Site templates, recipes and distribution developers