-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Make as many services private as possible #24104
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
Conversation
198fdbe
to
28dac38
Compare
REMAINING.PUBLIC.md
Outdated
security.acl.dbal.connection | ||
security.acl.provider | ||
security.encoder_factory | ||
security.firewall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is an event subscriber, could be made private to me
REMAINING.PUBLIC.md
Outdated
cache.app_clearer | ||
$commandId | ||
debug.templating.engine.php | ||
profiler.request_matcher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be made private to me, only injected
REMAINING.PUBLIC.md
Outdated
security.password_encoder | ||
session.handler | ||
session.storage | ||
session.storage.filesystem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flagged as "for BC" https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml#L72..L73
should we deprecate it on 3.4? (can't find the PR)
REMAINING.PUBLIC.md
Outdated
|
||
annotation_reader | ||
cache.app_clearer | ||
$commandId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must remain public, this is for non-lazy commands which are get()
at runtime
28dac38
to
487a823
Compare
REMAINING.PUBLIC.md
Outdated
annotation_reader | ||
cache.app_clearer | ||
$commandId | ||
debug.templating.engine.php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the debug one does not need to be public IMO. You should never get it by its debug.*
id (the templating.engine.php
should stay public though)
REMAINING.PUBLIC.md
Outdated
router | ||
security.access.decision_manager | ||
security.acl.cache | ||
security.acl.dbal.connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should not need to be public (if you need the DBAL connection yourselves dynamically, you should get it using the public ids given in DoctrineBundle)
REMAINING.PUBLIC.md
Outdated
templating | ||
templating.loader | ||
translator | ||
twig.loader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even this one should become private IMO. There is no reason to access it dynamically at runtime IMO.
REMAINING.PUBLIC.md
Outdated
cache.system | ||
cache_warmer <- required to bootstrap the kernel | ||
data_collector.cache | ||
data_collector.dump |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do collectors actually need to be public ? AFAIK, they are needed only by the profiler, and so could become private
REMAINING.PUBLIC.md
Outdated
|
||
### Remaining public services | ||
|
||
cache.adapter.* <- pools are private by default when created by config so not a pb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest adapters should become private in 4.0
REMAINING.PUBLIC.md
Outdated
security.csrf.token_manager | ||
security.firewall | ||
security.token_storage | ||
security.validator.user_password |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should become private, like other constraint validators
REMAINING.PUBLIC.md
Outdated
serializer | ||
session | ||
state_machine.abstract <- state machines created by config are public | ||
workflow.abstract <- workflows created by config are public |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't we make them private instead ? The documented way to get them is to use the registry AFAIK, not to get the service from the container
REMAINING.PUBLIC.md
Outdated
translator | ||
twig | ||
twig.controller.exception | ||
twig.controller.preview_error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are required to be public due to the routing referencing them, right ?
<argument type="service" id="request_stack" /> | ||
</service> | ||
|
||
<service id="assets.path_package" class="Symfony\Component\Asset\PathPackage" abstract="true" public="true"> | ||
<service id="assets.path_package" class="Symfony\Component\Asset\PathPackage" abstract="true"> | ||
<tag name="container.private" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the place where we actually need to apply this tag is in child services
ae67484
to
0d55972
Compare
4f8c41d
to
89e8e28
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. Fixed rather elegant 👍 is setPrivate an internal detail now? should it?
REMAINING.PUBLIC.md
Outdated
serializer <- for the base controller | ||
session <- for the base controller | ||
state_machine.abstract <- state machines created by config are public | ||
workflow.abstract <- workflows created by config are public |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. The registry is only here for convenience in twig.
Users should inject the right workflow in other services. Adding an extra layer will make the core harder to understand and to test. It's exactly like doctrine. People should inject the right repository, not the whole Doctrine Manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, then we can still make them private, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyrixx if you want them to inject it in the service, it can be private. Public is here for dynamic get.
But if they are meant to be the main services of the workflow component, they should indeed stay public for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because we need to access it from a controller or a command.
Not everyone are using controller/command as a service.
REMAINING.PUBLIC.md
Outdated
translation.extractor | ||
translation.loader | ||
translation.reader | ||
translation.writer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Nyholm do you think we should plan making private these translation.*/translator services in 4.0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
translator
must stay public. Otherwise, people using ContainerAware classes cannot use the translator layer anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, all theses services (above) could be private. except the security.authentication_utils
(for use in ContainerAware classes)
89e8e28
to
39c36dd
Compare
@ro0NL setPrivate is OK for eg bundles to me so they can do the same as we do here. |
39c36dd
to
0706e20
Compare
Guessed so. But are we sure about |
they don't need to do different things in 4.0, that's the solution. |
And in fact, they already don't do different things already - except for internal details. |
Yeah but |
locally, that's correct - making it so would just discard any benefits of introducing it. |
I think we need to improve the documentation about the difference between |
failures are false positives |
Very nice work! Imagining myself as someone new to Symfony, I would have issues/doubts with these services:
|
@javiereguiluz We still have some places where we are forced to |
command related services can be made private in 4.0 :) |
If the controllers are the only big area which cannot be made private.. Maybe the controller tag should be introduced to make this possible? |
There is already a tag to flag services as controllers ( |
Just to complete this. But |
@mvrhov I don't know anymore what you're talking about :) You don't have to use that tag at all, that's what I said. You just have to make your controllers public. |
@nicolas-grekas the thing that controllers must be public is more confusing than it looks. I can understand public services: you may inject this somewhere, so make it public. OK. But I don't inject or need or use or do anything with controllers. It's "a Symfony thing" and that's why I expect them to not be public. |
OK, I've no solution for that - and I don't think there is anything wrong in fact. A service really needs to be public for one and only one reason: bootstrapping.
all other uses are the bad sort of service locator. |
a3b2743
to
1936491
Compare
ping @symfony/deciders, one vote missing :) |
…kas) This PR was merged into the 3.4 branch. Discussion ---------- Make as many services private as possible | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | not yet | Fixed tickets | #23822 | License | MIT | Doc PR | - - [x] review the list of currently public services and validate which one should be turned private (noted as such with the `container.private` tag in this PR) - [x] rebase on top of #24103 - [x] implement the behavior described in #23822 (comment) - [x] add tests List of services that will be kept public: ### Remaining public aliases cache.app_clearer <- for the cache:pool:clear command to clear app pools $commandId <- for non-lazy commands which are get() at runtime router <- for the base controller templating <- for the base controller ### Remaining public services test.client <- for WebTestCase security.password_encoder <- for use in ContainerAware classes security.authentication_utils <- for use in ContainerAware classes filesystem <- for use in ContainerAware classes kernel <- for use in ContainerAware classes translator <- for use in ContainerAware classes validator <- for use in ContainerAware classes cache_clearer <- for the cache:clear command cache_warmer <- required to bootstrap the kernel cache.app <- for userland only cache.global_clearer <- for the cache:pool:clear command to clear all pools cache.system <- for userland only data_collector.dump <- required to have dump() work very early when booting the kernel event_dispatcher <- required to wire console apps form.factory <- for the base controller http_kernel <- required to bootstrap the kernel profiler <- used in tests request_stack <- for the base controller routing.loader <- used by routing security.authorization_checker <- for the base controller security.csrf.token_manager <- for the base controller security.token_storage <- for the base controller serializer <- for the base controller session <- for the base controller state_machine.abstract <- userland state machines workflow.abstract <- userland workflows twig <- for the base controller twig.controller.exception <- controllers referenced by routing twig.controller.preview_error <- controllers referenced by routing var_dumper.cloner <- required to have dump() work very early when booting the kernel web_profiler.controller.exception <- controllers referenced by routing web_profiler.controller.profiler <- controllers referenced by routing web_profiler.controller.router <- controllers referenced by routing Commits ------- 1936491 Make as many services private as possible
…h BC layer (nicolas-grekas) This PR was merged into the 3.4 branch. Discussion ---------- [DI] Turn services and aliases private by default, with BC layer | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #20048 | License | MIT | Doc PR | - With this PR, all services and aliases are made private by default. This is done in a BC way, thanks to the layer introduced in #24104. We will require bundles to explicitly opt-in for "public", either using "defaults", or stating `public="true"` explicitly. Same in DI extension, where calling `->setPublic(true)` will be required in 4.0. Commits ------- 9948b09 [DI] Turn services and aliases private by default, with BC layer
@nicolas-grekas After upgrading to 3.4, I'm getting this deprecation warning:
This is the culprit:
|
The |
Yeah, I discovered a bundle is at fault... Please ignore... |
…tainer (see #1383). Description ----------- I searched the Contao source code for instances of `getContainer()->get('...');` occurrences, filtered out `contao` prefixed services and "uniquified" the resulting array. ``` assets.packages database_connection doctrine.dbal.default_connection event_dispatcher filesystem fragment.handler lexik_maintenance.driver.factory monolog.logger.contao request_stack router security.authentication_utils security.authorization_checker security.firewall.map security.logout_url_generator security.token_storage session swiftmailer.mailer translator ``` After intersecting this array to the one found in this ticket (future public services) [this ticket](symfony/symfony#24104), we end up with: ``` assets.packages database_connection doctrine.dbal.default_connection fragment.handler lexik_maintenance.driver.factory monolog.logger.contao security.firewall.map security.logout_url_generator swiftmailer.mailer ``` I added those to our `MakeServicesPublicPass` and made sure it will also find aliases instead of definitions only. Unfortunately I'm not sure if I really caught all direct service references. Do you have any other ideas? Commits ------- d6df8a8 Make all services public that we are retrieving directly from the container. 579c113 CS Fix a93083a Test all services in the unit test.
…the container (see contao#1383). Description ----------- I searched the Contao source code for instances of `getContainer()->get('...');` occurrences, filtered out `contao` prefixed services and "uniquified" the resulting array. ``` assets.packages database_connection doctrine.dbal.default_connection event_dispatcher filesystem fragment.handler lexik_maintenance.driver.factory monolog.logger.contao request_stack router security.authentication_utils security.authorization_checker security.firewall.map security.logout_url_generator security.token_storage session swiftmailer.mailer translator ``` After intersecting this array to the one found in this ticket (future public services) [this ticket](symfony/symfony#24104), we end up with: ``` assets.packages database_connection doctrine.dbal.default_connection fragment.handler lexik_maintenance.driver.factory monolog.logger.contao security.firewall.map security.logout_url_generator swiftmailer.mailer ``` I added those to our `MakeServicesPublicPass` and made sure it will also find aliases instead of definitions only. Unfortunately I'm not sure if I really caught all direct service references. Do you have any other ideas? Commits ------- d6df8a8a Make all services public that we are retrieving directly from the container. 579c1138 CS Fix a93083a2 Test all services in the unit test.
container.private
tag in this PR)List of services that will be kept public:
Remaining public aliases
cache.app_clearer <- for the cache:pool:clear command to clear app pools
$commandId <- for non-lazy commands which are get() at runtime
router <- for the base controller
templating <- for the base controller
Remaining public services
test.client <- for WebTestCase
security.password_encoder <- for use in ContainerAware classes
security.authentication_utils <- for use in ContainerAware classes
filesystem <- for use in ContainerAware classes
kernel <- for use in ContainerAware classes
translator <- for use in ContainerAware classes
validator <- for use in ContainerAware classes
cache_clearer <- for the cache:clear command
cache_warmer <- required to bootstrap the kernel
cache.app <- for userland only
cache.global_clearer <- for the cache:pool:clear command to clear all pools
cache.system <- for userland only
data_collector.dump <- required to have dump() work very early when booting the kernel
event_dispatcher <- required to wire console apps
form.factory <- for the base controller
http_kernel <- required to bootstrap the kernel
profiler <- used in tests
request_stack <- for the base controller
routing.loader <- used by routing
security.authorization_checker <- for the base controller
security.csrf.token_manager <- for the base controller
security.token_storage <- for the base controller
serializer <- for the base controller
session <- for the base controller
state_machine.abstract <- userland state machines
workflow.abstract <- userland workflows
twig <- for the base controller
twig.controller.exception <- controllers referenced by routing
twig.controller.preview_error <- controllers referenced by routing
var_dumper.cloner <- required to have dump() work very early when booting the kernel
web_profiler.controller.exception <- controllers referenced by routing
web_profiler.controller.profiler <- controllers referenced by routing
web_profiler.controller.router <- controllers referenced by routing