AutowireTrait has wrong behavior for literal string values

Created on 30 June 2025, 1 day ago

Problem/Motivation

The Autowire attribute from symfony has a first parameter which is for a literal value.
The second parameter 'service' is for actual service ids.
Also, prepending '@' does indicate a service id.
(The conversion happens inside the Autowire attribute class. If it is a service, we get a Reference object.)

class C {
  public function __construct(
    #[Autowire('yellow')] string $color,
    #[Autowire(service: 'logger.channel.abc')] LoggerInterface $abcLogger,
    #[Autowire('@logger.channel.xyz')] LoggerInterface $xyzLogger,
  ) {
    assert($color === 'yellow');
  }
}

This works in a regular service, but not in classes in Drupal that use AutowireTrait.
Here, the string 'yellow' would be understood as a service id.

class C {
  use AutowireTrait;
  public function __construct(
    #[Autowire('yellow')] TheColorYellow $yellow,
  ) {}
}

Steps to reproduce

Playing around with example code as above should reproduce the problem.

Proposed resolution

Fixing this now has to be done in a BC-friendly way.
Luckily we do have the parameter type available:

- If $autowire->value is a Reference object, inject a service.
- If $autowire->value is a literal string, and the parameter expects a string, inject the literal string value.
- If $autowire->value is a literal string, but the parameter expects an object, or has no type, or an ambiguous union type, treat the string as a service id, but trigger a deprecation "Don't pass a service id to the first parameter of Autowire".

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

11.0 🔥

Component

base system

Created by

🇩🇪Germany donquixote

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024