New in Symfony 5.1: Autowire public typed properties
March 10, 2020 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Sébastien Morel
in #34769.
Typed properties, introduced in PHP 7.4, are one of the most important features added by PHP in years. In Symfony 5.1 we're implementing new features based on them, such as extracting typed properties info using the PropertyInfo component.
Consider this example using typed properties:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Twig\Environment;
class SomeServiceClass
{
/** @required */
public Environment $twig;
public function someMethod()
{
$this->twig->render('...');
// ...
}
}
In previous Symfony versions, this example wouldn't work because Twig service
is not properly injected. In Symfony 5.1, this example will work as expected.
The reason is that Symfony 5.1 autowires all public properties that are typed
with classes related to services and which include the @required
annotation.
Some things to consider:
- Only public properties are autowired; protected and private properties will never be autowired to avoid any confusing behavior;
- This is in practice equivalent to setter injection, which has drawbacks and it should be used only in very specific scenarios.
This new feature is just one of the many tools that Symfony gives you to automate the configuration of how services/objects should be created. If it doesn't fit your way of developing applications, it's OK to keep using the traditional service injection based on constructors and private properties.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
@Martin I'd guess it's possible, though I don't think doing so is a very good idea as it influences the "state" of other instances of your service.
We don't recommend anyone using setter injection in the docs, so we won't also rewrite all examples to use autowired public properties.
This builds on the idea that contributions are following a master plan. That's not the case: ppl contribute what they want.
> why Symfony is adding a feature which is obviously a bad practice
It's as a bad practice as using setters, yet setters are just the right solution to some problems. Same here: it's not Symfony's role to decide what should be possible or not. The DI container is here to wire code that ppl wrote, this is one possible. That's all folks...
I understand your second point.
For objecting like everyone else, it's not better to call the annotation @Inject.
I see this as a BIG improvement in readability but I can understand why people are concerned about "encapsulation". In the end, we always use a class property to store the injected service but it can quickly be a mess if the services are mixed with other properties.
Do you think that it is possible to enable it from the config, or enable a hybrid version where only annotated property are autowired, an annotation like "@Autowire" for instance ?