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

Comments

donquixote created an issue. See original summary.

godotislate’s picture

The Autowire attribute also can be passed container parameters, so those might be something to be accounted for by the trait as well.

Technically also expressions and env as well, but I don't think the Drupal container supports those atm.

mstrelan’s picture

Technically also expressions and env as well, but I don't think the Drupal container supports those atm.

This has been explored a bit in #3464357: Add a trait for autowiring properties in tests, I believe it requires the addition of symfony/expression-language.

godotislate’s picture

donquixote’s picture

I think for now we want to make sure it works as advertised for for a limited set of supported scenarios.
Later we can incrementally add support for advanced autowire features.

godotislate’s picture

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.