Skip to content

[DI] Deprecate (un)setting pre-defined services #21533

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

Merged
merged 1 commit into from
Feb 12, 2017

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Feb 4, 2017

Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? yes
Tests pass? no
Fixed tickets #19192
License MIT
Doc PR -

This PR is the subset of #19668 that fixes #19192: it deprecates (un)setting pre-defined services.
This opens the path to some optimizations in the dumped container in 4.0.

@@ -190,7 +190,14 @@ public function set($id, $service)
@trigger_error(sprintf('Unsetting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
unset($this->privates[$id]);
} else {
@trigger_error(sprintf('Setting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0. A new public service will be created instead.', $id), E_USER_DEPRECATED);
@trigger_error(sprintf('Setting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this tail:

A new public service will be created instead.

it's not obvious to me that this will be the behavior we should implement in 4.0 :)

@nicolas-grekas nicolas-grekas force-pushed the di-deprec-set branch 2 times, most recently from bcb4b45 to 90eb386 Compare February 4, 2017 19:32
@ro0NL
Copy link
Contributor

ro0NL commented Feb 5, 2017

Shouldnt we deprecate the null scenario first? So other conditional deprecations are practically not needed.

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Feb 5, 2017

That's the point of this PR: #19668 is deprecating much more than technically required to enhance the dumped containers in 4.0. In fact, even if I listen to the "best practice" arguments in #19668, we know that forbidding altogether not-best-practices can break legitimate edge-case use cases (remember the deprecation of "get" in non dumped containers that we reverted). Thus, I'm not sure at all we should merge #19668 - but I'm sure we should merge this one, because it will make SF4 better at the technical level.

@nicolas-grekas nicolas-grekas changed the title [DI] Deprecate Container::set for nulls, initialized and alias services [DI] Deprecate (un)setting pre-defined services Feb 5, 2017
@stof
Copy link
Member

stof commented Feb 7, 2017

👍

@fabpot
Copy link
Member

fabpot commented Feb 12, 2017

Thank you @nicolas-grekas.

@fabpot fabpot merged commit fdb2140 into symfony:master Feb 12, 2017
fabpot added a commit that referenced this pull request Feb 12, 2017
This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Deprecate (un)setting pre-defined services

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | no
| Fixed tickets | #19192
| License       | MIT
| Doc PR        | -

This PR is the subset of #19668 that fixes #19192: it deprecates (un)setting pre-defined services.
This opens the path to some optimizations in the dumped container in 4.0.

Commits
-------

fdb2140 [DI] Deprecate (un)setting pre-defined services
@nicolas-grekas nicolas-grekas deleted the di-deprec-set branch February 16, 2017 22:45
@fabpot fabpot mentioned this pull request May 1, 2017
@xkobal
Copy link
Contributor

xkobal commented May 17, 2017

Hi @nicolas-grekas

I am testing SF 3.3BETA1 and I've got a trouble with that Pull Request:

  • What about mock of service in functional test ?

When I try to replace Service with $kernel->getContainer()->set() I have a deprecation notice:

Setting the "SERVICE" pre-defined service is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0

What is my solution for this kind of functional tests ?

Thanks for the answer.

@stof
Copy link
Member

stof commented May 17, 2017

@xkobal injecting a PHPUnit mock to replace a service instance is a very fragile setup: if any other services depending on this service got instantiated already before your set call, it will keep using the other object rather than the mock. Replacing service instances at runtime cannot work reliably (which is exactly why we deprecated it).
Loading specific config for functional tests is indeed a much more reliable alternative. It does not allow to use mocks generated by PHPUnit though, or at least not without much pain. But it can be used by injecting hand-crafted mocks (i.e. custom implementations of your interface)

@OwlyCode
Copy link
Contributor

The config approach is indeed much stronger. I also used to mock services with the set() method, heavily inspired by http://blog.lyrixx.info/2013/04/12/symfony2-how-to-mock-services-during-functional-tests.html (at the boot before any service gets used by the test).

@xkobal
Copy link
Contributor

xkobal commented May 17, 2017

I'm agree with you on that point, and I'll change my tests, but, thats a way to test services, very very used on a lot of project ! It'll be a painful point for a lot of projects to upgrade to SF 3.3

Thanks for your answers.

@nicolas-grekas
Copy link
Member Author

Note that you don't need to fix the deprecations when moving to 3.3.
But you will when moving to 4.0.

@xkobal
Copy link
Contributor

xkobal commented May 17, 2017

I never upgrade a project letting some deprecations, our CI is failing on phpunit tests when there are some deprecations, but that's our choice, others can ignore them.

@stof
Copy link
Member

stof commented May 17, 2017

Well, you can mark these tests as @legacy to avoid making them fail temporarily, to give you time to migrate the tests, if that takes time. This is the whole point of deprecations: you can migrate progressively (I also prefer removing deprecations as fast as possible, but for some of them, it may require more time)

fabpot added a commit that referenced this pull request Jul 17, 2017
…rvices (ro0NL)

This PR was merged into the 4.0-dev branch.

Discussion
----------

[DI] Removed deprecated setting private/pre-defined services

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | symfony/symfony-docs#... <!--highly recommended for new features-->

See #21533, #19708 and #19146

@nicolas-grekas privates should be excluded from `getServiceIds` right? i also wondered.. did we forget to deprecate checking privates with `initialized()`?

Commits
-------

9f96952 [DI] Removed deprecated setting private/pre-defined services
@scott-r-lindsey
Copy link

This is going to be difficult for my use case -- I replace guzzle clients with guzzle mock handlers loaded with responses (per test), and I validate both the response and the request made.

@chalasr "use config files" assumes that a service can be reconfigured (or replaced) by way of configuration alone, and also that tests can all use the same configuration.

@stof We're talking about testing here -- tests are supposed to be fragile.

This isn't looking good. Am I going to have to forgo booting a kernel and just build my services by hand before testing them? Or, perhaps, I create intermediary objects that can know how to replace themselves on demand? Either way, I have to take over work that I could previously count on my framework to do.

@nicolas-grekas
Copy link
Member Author

Please open an issue to discuss this.

@scott-r-lindsey
Copy link

I'm adding a comment to #23311.

@chalasr
Copy link
Member

chalasr commented Aug 2, 2017

You should open a new issue really. Comments on closed tickets aren't tracked.

@scott-r-lindsey
Copy link

Thanks @chalasr I've opened #23772

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deprecate Container::set() for non-synthetic services
9 participants