-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[RFC] Proposal to simplify the autowiring of container parameters #23718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Another solution is merging #22187 which allows to inject named arguments in all services of a file :) Edit: with your example, it could look like: services:
bind:
$argument1: '%kernel.project_dir%'
$argument2: '%app.container_param%'
$argument3: '%app.another_param%'
# ...
App\:
# ... This way you don't end up with hundreds of useless lines but you keep the advantages of being explicit and you don't inject a class that imo belongs to sf internals. |
@GuilhemN yes, your proposal could work too ... although I don't like that it introduces yet another configuration option that users must learn. |
There's not much to learn, the syntax is the same as arguments. The difference is that it can be used for arguments and method calls arguments and that its content doesn't need to be used in all services for resources/defaults. This could replace |
I was referring to |
@javiereguiluz why can't you already inject the parameter bag? |
For sure but that's not much to learn, there are options that are far less useful imo that we still introduced and documented (configurators, shared). |
@theofidry have you tested it? Because I can't make that work at all 😞 |
I guess you first have to register the services:
Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface:
factory: ["@service_container", getParameterBag] |
|
What if you explicitly don't autowire this service? |
@javiereguiluz, by injecting ParameterBag or the whole container you make dependencies of your class unclear. If you feel that you repeat the same tasks of declaring some classes' arguments again and again, shouldn't you consider refactoring? |
What about introducing a ConfigurationClass? It takes all scalars you need, delivers them through getters, and should be autowirable |
@javiereguiluz to be honest that's one thing I don't like about auto-wiring: bending designs to make it work better. IMO auto-wiring is a tool to help, not something you base your application on. So in your case I would say that yes: you inject scalar values, you need to manually wire them. And Symfony is not alone: even in frameworks with full auto-wiring like Laravel you need to do that. Now if you really want to go that way:
There may be other solutions like refactoring some pieces, using abstract service definitions, but hard to tell without your code. |
#22187 is exactly the solution we created to solve this issue, I think we just need everyone to focus on it so that it gets some support and is merged. |
#22187 is just the explicit way to code your own conventions in configuration. Contrary to a proposal like this one, or the annotation based ones, that force you to design/write your code in some way for the need of auto-configuration, which is doing things reverse side to me. |
Let's close this in favor of #22187. Thanks! |
This PR was squashed before being merged into the 3.4 branch (closes #22187). Discussion ---------- [DependencyInjection] Support local binding | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files --> | BC breaks? | no | Deprecations? | no <!-- don't forget updating UPGRADE-*.md files --> | Tests pass? | yes | Fixed tickets | #22167, #23718 | License | MIT | Doc PR | > A great idea came out on Slack about local bindings. > We could allow injecting services based on type hints on a per service/file basis: > ```yml > services: > _defaults: > bind: > BarInterface: '@usual_bar' > > Foo: > bind: > BarInterface: '@alternative_bar' > $quz: 'quzvalue' > ``` > > This way, `@usual_bar` will be injected in any parameter type hinted as `BarInterface` (in a constructor or a method signature), but only for this service/file. > Note that bindings could be unused, giving a better solution than #22152 to #21711. > > As named parameters are usable in arguments, bindings could be usable in arguments too: > ```yml > services: > Foo: > arguments: > BarInterface: '@bar' > ``` ~Named parameters aren't supported yet.~ Edit: > Note that bindings could be unused Current behavior is throwing an exception when a binding is not used at all, in no services of a file if it was inherited from `_defaults` or in no services created from a prototype. It will pass if the bindings are all used in at least one service. Commits ------- 81f2652 [DependencyInjection] Support local binding
I think this approach to improve development speed is important. Because to add an argument in a service I need to move to other file, search service (or create his definition), add argument, when I back to my service I lost my focus for this repetitive tasks and if the project is huge it is worst.... This kind of things is not magic is to be efficient... I know all symfony programmers must know how services system works but in 90% of time we need to save our time. This problem is the same to add a "TAG", "priorities" ... in a service. What do you think about the use of Annotations? |
See #25288, which could be used instead. |
The Problem
These days I'm updating some legacy Symfony applications to use Flex and modern Symfony practices. The first step was autowiring services. I loved the change. Everything is much better now and the automation (not magic) added by autowiring is fantastic to improve your productivity and code quality.
However, there's a minor thing about autowiring that bugged me: autowiring scalars.
I understand that this cannot be solved without adding magic. But in my case, 100% of scalar values are container parameters. And I have literally hundreds of lines of service config like this:
It's so boring to do this. And so useless! I'd like to propose another way to solve this.
The Proposal
What if we allow to inject
ParameterBag
to inject all container parameters?The above example would now look like this:
And no YAML/XML config would be needed for services like this.
Comments
*.class
params) and params is an array which is easily cacheable by PHP 7. Impact in memory consumption should be minimal or null? To be confirmed...The text was updated successfully, but these errors were encountered: