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".
Comments
Comment #2
godotislateThe 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.
Comment #3
mstrelan commentedThis 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.Comment #4
godotislateYeah, and env support has hit a snag in #3249970: [PP-1] Support setting service parameters via environment variables.
Comment #5
donquixote commentedI 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.
Comment #6
godotislateCreated #3558292: Support passing container parameters with the Autowire attribute in AutowireTrait and AutowiredInstanceTrait for container parameters.