Skip to content

Private services stay public when required by more than one service #12588

Closed
@bestform

Description

@bestform

The documentation says, that a service, that you declare private, will not be available via the get method of the compiled container (see: http://symfony.com/doc/current/components/dependency_injection/advanced.html)

This is not true. A private service will only be removed by the RemoveUnusedDefinitionsPass compiler pass, if it is only used by one other service. In this case, the container doesn't need to keep track of the instance, as it can just instantiate one instance of the private service in the getter of the service in need and forget about it.

But should the service be used by more than one service, the container keeps track of the lazily loaded instance by not removing the service.

This in itself isn't bad, but the problem is, that at this point, the container also provides the private service publicly to its users.

I've written two new test cases, which reproduce the problem. The first test case (testPrivateServiceIsNotAccessibleWhenRequiredByOneOtherService) is successful, the second one (testPrivateServiceIsNotAccessibleWhenRequiredByMoreThanOneOtherService) fails, as the private service hasn't been removed.

You can see the test cases here: https://github.com/bestform/symfony/compare/test-for-private-services

I would suggest that the container keeps track of the instances internally while forbidding the access from the outside to be consistent with the documentation and in general to be more intuitive. Private services should be private, no matter how the compilation pass of the container is able to optimize their usage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions