Problem/Motivation
Symfony allows you to specify _defaults key in your services.yml file. This allows you to specify defaults for all of your services. See https://symfony.com/doc/current/service_container.html
In Symfony it often looks like
# config/services.yaml
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
# ...
Whilst autoconfigure is not relevant yet it would be nice for a module to be able to declare all of its services as public: false (if for example it wants to prevent the service locator pattern - yes this is hard is Drupal because plugin managers and events don't work with them but maybe in the future) and autowire will be supported by #3021803: Document and add tests for service autowiring.
Proposed resolution
Implement this by copying code from YamlFileLoader once #3021803: Document and add tests for service autowiring has landed.
Remaining tasks
User interface changes
None
API changes
@todo
Data model changes
None
Release notes snippet
@todo
| Comment | File | Size | Author |
|---|---|---|---|
| #31 | 3021898-9.5.x-31.patch | 21.76 KB | alexpott |
Issue fork drupal-3021898
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
alexpottCreated a meta
Comment #3
alexpottPatch includes #3021803: Document and add tests for service autowiring
Comment #4
alexpottComment #5
opdaviesI've given the patch a quick test and it seems to work well.
It's allowed me to change my drupalversary.services.yml from:
to:
Comment #7
aaronbaumanAutowiring is already supported, as of #2611816: Update to symfony 2.8, so I don't think this needs to be postponed on #3021803: Document and add tests for service autowiring since this thread is about support for
_defaults, not autowiring specifically.This patch is a re-roll of #3 and includes test coverage for the new
_defaults:autowiring,tags, andpublic.There are still some TODOs in the code, not sure what to do with those.
Comment #12
longwaveTagging as this looks like a good next target if #3021803: Document and add tests for service autowiring gets in.
Comment #13
longwaveI think it's OK to allow both these, autoconfiguration would be nice in the future (e.g. not having to tag event subscriber services manually) as would argument binding (so we can autowire container parameters). We might as well move towards allowing everything Symfony allows unless there is good reason not to.
Comment #14
alexpott@longwave I very much agree but I wasn't sure if we actually supported these things yet and therefore whether allowing them to be defaulted was a kind of over promise.
Comment #15
longwaveI guess we could add tests for both binding and autoconfiguration, as both are handled by Symfony compiler passes, and with a bit of support here should hopefully just work. Autoconfiguration would also need us to support _instanceof though - maybe we should leave these to a followup?
Comment #16
longwaveRerolled with some minor changes to make tests pass following #3187074: [Symfony 5] Services are private by default
Still need to remove the bind and autoconfigure parts, and Symfony's YamlFileLoader has also moved on since the original patch - I think we should bring any new additions here in line with latest Symfony.
Comment #17
longwaveMake cspell happy.
Comment #19
longwaveCopied the relevant parts of
parseDefaults()andparseDefinition()directly from Symfony 4.4 so we are closer to upstream. We can do more, but that's out of scope of this issue and may have some BC concerns (Symfony does a lot of additional validation that we don't currently do, for example).Comment #20
longwaveNW for MR feedback.
Comment #21
longwaveAdded unit tests for all exceptions touched here in YamlFileLoader.
Comment #24
alexpottI think this looks great - I've re-created the branch against 10.0.x so it can be tested against Symfony 6. It'd be great to make some progress here to bring our container more into line with Symfony's upstream.
Comment #25
alexpottNote that the 10.0.x branch also applies to 9.4.x so I'm going to trigger a run against Symfony 4 there...
Comment #26
alexpottSo this is fun... I've fixed the MR for Drupal 10. Some of the code in the upstream YamlFileLoader has moved around because of how \Symfony\Component\DependencyInjection\ChildDefinition has changed (it no longer calls
$this->setPrivate(false);in its constructor). This means that now we need separate changes for 9.4.x and 10.0.x. The patch in #25 is the correct change for 9.4.x and the latest in the MR is (hopefully) the correct change for 10.0.x.Here's the diff of the 2 approaches:
Comment #28
daffie commentedI am missing testing for when $name is set and is not a string.
Missing testing for the $value is null.
With this change will, when the $service['parent'] is set, not be set public by default. Is that what we want? And will this be a BC break? Not sure, just asking the question.
Can we improve the docblock? It is not very informing now.
Can we add a test to see if overriding the _default autowire is true works.
Nitpick: Can we put this on a single line or move the last ");" to the next line.
Can we add testing that the _default tags are still there too and are not lost.
Needs a docblock.
Comment #29
alexpottThanks for the review @daffie
Comment #30
daffie commentedAll code changes look good to me.
All my points have been addressed.
Testing has been added.
I have created a CR.
For me it is RTBC.
Comment #31
alexpottHere's a patch for 9.5.x which has @daffie's review fixes merged on top of #25. Because of the differences upstream 10.0.x and 9.5.x need different patches - see #26 for why.
Comment #33
daffie commentedTestbot is happy again. Back to RTBC.
Comment #35
catchCommitted/pushed/cherry-picked the respective patches to 10.1.x/10.0.x and 9.5.x, thanks!
Since this isn't disruptive or an API change etc., I don't think it needs a release note, just the CR seems fine. If we start changing core's service definitions, we should probably do one then.
Comment #37
donquixote commentedDo we have a follow-up issue to re-add the "bind"?
I think it would be quite useful to have :)
EDIT: Yes, this is the follow-up: #3108565: Update the Yaml file Loader functionality to simplify service configuration