Skip to content

[DependencyInjection] Container::set() is useless if the entry is an alias #16461

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

Closed
mnapoli opened this issue Nov 4, 2015 · 10 comments
Closed

Comments

@mnapoli
Copy link
Contributor

mnapoli commented Nov 4, 2015

In my integration tests I want to replace a service by a fake implementation. For example I want to temporarily replace the event_dispatcher by a mock that will store all triggered events:

$container->set('event_dispatcher', $fakeDispatcher);

The problem is that event_dispatcher is an alias, and Container::get() first resolves aliases before trying to find the entry.

That makes Container::set() silently useless when setting an entry that is an alias.

IMO this is a bug, and I see 2 solutions (by order of preference), feel free to suggest alternatives:

  • set() should erase any existing alias because it should just work
  • set() should throw an exception if setting an alias

I can implement the solution if one is chosen.

@ro0NL
Copy link
Contributor

ro0NL commented Nov 16, 2015

  • Set the actually aliassed key?

@mnapoli
Copy link
Contributor Author

mnapoli commented Nov 16, 2015

Yes but:

  • it's silently useless, which is very unhelpful
  • it leads to this for example (what I use in some tests):
$container->set('event_dispatcher', $dispatcher); // if debug=false
$container->set('debug.event_dispatcher', $dispatcher); // if debug=true

No great… At all.

I don't see a reason why Container::set() should not work in that case.

@Taluu
Copy link
Contributor

Taluu commented Nov 16, 2015

I think the proper option should be the be able to erase that when building the container (ContainerBuilder) but on the Container it should be forbidden to do so

@mnapoli
Copy link
Contributor Author

mnapoli commented Nov 16, 2015

Why?

@Taluu
Copy link
Contributor

Taluu commented Nov 16, 2015

Once the container has been built, it shouldn't be changed so easily IMO (I may be wrong though ; if it is the case, the option of replacing the service is still a good one IMO)

@stof
Copy link
Member

stof commented Nov 16, 2015

@Taluu set makes sense at runtime, not during container building (the ContainerBuilder has the method, because you can keep using it as the runtime container when you don't dump an optimized container). during container building, you should be setting definitions

@wpeereboom
Copy link

@mnapoli Did you find or build a work arround ? I run into the same problems. I suggest the option to set and overwrite the existing alias makes most sense. Let me know if I can be at any help.

mnapoli added a commit to mnapoli/symfony that referenced this issue Feb 9, 2016
…existing aliases

`Container::set()` now overrides any previously alias defined with the same name.
@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 9, 2016

@wpeereboom I just opened a pull request to fix this: #17742

@wpeereboom
Copy link

@mnapoli Great, thanks

fabpot pushed a commit that referenced this issue Feb 12, 2016
…g aliases

`Container::set()` now overrides any previously alias defined with the same name.
fabpot added a commit that referenced this issue Feb 12, 2016
…aliases (mnapoli)

This PR was submitted for the master branch but it was merged into the 2.3 branch instead (closes #17742).

Discussion
----------

[DependencyInjection] Fix #16461 Container::set() replace aliases

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

`Container::set()` now overrides any previously alias defined with the same name. Please see #16461 for the background.

Example:

- given `event_dispatcher` is an alias to `debug.event_dispatcher`
- when I run: `$container->set('event_dispatcher', new FakeEventDispatcher)`
- *before this patch*: nothing happens
- *after this patch*: the `event_dispatcher` is now my fake event dispatcher

Commits
-------

be85d16 [DependencyInjection] Fix #16461 Let Container::set() replace existing aliases
@fabpot fabpot closed this as completed Feb 12, 2016
nicolas-grekas added a commit that referenced this issue Feb 13, 2016
* 2.3:
  [DomCrawler] Clarify the value returned by getPhpFiles()
  [DependencyInjection] Fix #16461 Let Container::set() replace existing aliases
  Added more exceptions to singularify method
nicolas-grekas added a commit that referenced this issue Feb 13, 2016
* 2.7:
  [VarDumper] Fix tests on PHP 7
  [DomCrawler] Clarify the value returned by getPhpFiles()
  [DependencyInjection] Fix #16461 Let Container::set() replace existing aliases
  avoid (string) catchable fatal error for instances of __PHP_Incomplete_Class
  remove unnecessary retrieval and setting of data
  avoid (string) catchable fatal error for __PHP_Incomplete_Class instances
  sendContent return as parent.
  [FrameworkBundle] Fix a typo
  Added more exceptions to singularify method
nicolas-grekas added a commit that referenced this issue Feb 13, 2016
* 2.8:
  [VarDumper] Fix tests on PHP 7
  [DomCrawler] Clarify the value returned by getPhpFiles()
  [DependencyInjection] Fix #16461 Let Container::set() replace existing aliases
  avoid (string) catchable fatal error for instances of __PHP_Incomplete_Class
  remove unnecessary retrieval and setting of data
  Update validators.fr.xlf
  avoid (string) catchable fatal error for __PHP_Incomplete_Class instances
  sendContent return as parent.
  [DomCrawler] Remove the overridden getHash() method to prevent problems when cloning the crawler
  [FrameworkBundle] Fix a typo
  Added more exceptions to singularify method
  Add width attribute on SVG
  [FrameworkBundle] Support autowiring for TranslationInterface
  [WebProfiler] Fixed styles for search block and menu profiler for IE Edge

Conflicts:
	src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php
	src/Symfony/Component/DomCrawler/Crawler.php
nicolas-grekas added a commit that referenced this issue Feb 13, 2016
* 3.0:
  [VarDumper] Fix tests on PHP 7
  [DomCrawler] Clarify the value returned by getPhpFiles()
  [DependencyInjection] Fix #16461 Let Container::set() replace existing aliases
  avoid (string) catchable fatal error for instances of __PHP_Incomplete_Class
  remove unnecessary retrieval and setting of data
  Update validators.fr.xlf
  avoid (string) catchable fatal error for __PHP_Incomplete_Class instances
  sendContent return as parent.
  [DomCrawler] Remove the overridden getHash() method to prevent problems when cloning the crawler
  [FrameworkBundle] Fix a typo
  Added more exceptions to singularify method
  Add width attribute on SVG
  [FrameworkBundle] Support autowiring for TranslationInterface
  [Validator] remove obsolete context and PropertyAccess code
  [WebProfiler] Fixed styles for search block and menu profiler for IE Edge
emodric added a commit to emodric/LegacyBridge that referenced this issue Mar 1, 2016
In Symfony 2.7.0 - 2.7.9, this line did nothing, since `ezpublish_legacy.kernel`
is an alias and `Container::set` never did anything with aliases.

In Symfony 2.7.10, setting an alias to a new value basically converts the
alias definition to service definition, meaning that `ezpublish_legacy.kernel`
will not point to `ezpublish_legacy.kernel.lazy` any more, thus making the alias
invalid next time `ezpublish_legacy.kernel.lazy` is rebuilt.

See symfony/symfony#16461 for details
emodric added a commit to emodric/LegacyBridge that referenced this issue Mar 2, 2016
In Symfony 2.7.0 - 2.7.9, this line did nothing, since `ezpublish_legacy.kernel`
is an alias and `Container::set` never did anything with aliases.

In Symfony 2.7.10, setting an alias to a new value basically converts the
alias definition to service definition, meaning that `ezpublish_legacy.kernel`
will not point to `ezpublish_legacy.kernel.lazy` any more, thus making the alias
invalid next time `ezpublish_legacy.kernel.lazy` is rebuilt.

See symfony/symfony#16461 for details
@Jean85
Copy link
Contributor

Jean85 commented Mar 16, 2016

This introduced an error in my case.

When you have an alias of an alias, it overwrites just the first alias, without cascading.
This helped me uncover a bug, and I fixed it setting directly the root service instead of the alias; but I'm not sure if it creates a BC.

Example: Doctrine default EM

$container->set('doctrine.orm.entity_manager', $fake);
$container->get('doctrine')->getManager(); // !== $fake, it uses 'doctrine.orm.default_entity_manager', which aliases to the default connection EM

Jean85 added a commit to facile-it/paraunit-testcase that referenced this issue Mar 16, 2016
ostrolucky pushed a commit to ostrolucky/symfony that referenced this issue Mar 25, 2018
* 2.8:
  [VarDumper] Fix tests on PHP 7
  [DomCrawler] Clarify the value returned by getPhpFiles()
  [DependencyInjection] Fix symfony#16461 Let Container::set() replace existing aliases
  avoid (string) catchable fatal error for instances of __PHP_Incomplete_Class
  remove unnecessary retrieval and setting of data
  Update validators.fr.xlf
  avoid (string) catchable fatal error for __PHP_Incomplete_Class instances
  sendContent return as parent.
  [DomCrawler] Remove the overridden getHash() method to prevent problems when cloning the crawler
  [FrameworkBundle] Fix a typo
  Added more exceptions to singularify method
  Add width attribute on SVG
  [FrameworkBundle] Support autowiring for TranslationInterface
  [WebProfiler] Fixed styles for search block and menu profiler for IE Edge

Conflicts:
	src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php
	src/Symfony/Component/DomCrawler/Crawler.php
ostrolucky pushed a commit to ostrolucky/symfony that referenced this issue Mar 25, 2018
* 3.0:
  [VarDumper] Fix tests on PHP 7
  [DomCrawler] Clarify the value returned by getPhpFiles()
  [DependencyInjection] Fix symfony#16461 Let Container::set() replace existing aliases
  avoid (string) catchable fatal error for instances of __PHP_Incomplete_Class
  remove unnecessary retrieval and setting of data
  Update validators.fr.xlf
  avoid (string) catchable fatal error for __PHP_Incomplete_Class instances
  sendContent return as parent.
  [DomCrawler] Remove the overridden getHash() method to prevent problems when cloning the crawler
  [FrameworkBundle] Fix a typo
  Added more exceptions to singularify method
  Add width attribute on SVG
  [FrameworkBundle] Support autowiring for TranslationInterface
  [Validator] remove obsolete context and PropertyAccess code
  [WebProfiler] Fixed styles for search block and menu profiler for IE Edge
jeromegamez added a commit to sport1online/ezpublish-kernel that referenced this issue Sep 21, 2018
Taken from ezsystems/LegacyBridge@c5bf6c2

This fixes the broken content preview as described in https://jira.ez.no/browse/EZP-25551

Original comment:

In Symfony 2.7.0 - 2.7.9, this line did nothing, since `ezpublish_legacy.kernel`
is an alias and `Container::set` never did anything with aliases.

In Symfony 2.7.10, setting an alias to a new value basically converts the
alias definition to service definition, meaning that `ezpublish_legacy.kernel`
will not point to `ezpublish_legacy.kernel.lazy` any more, thus making the alias
invalid next time `ezpublish_legacy.kernel.lazy` is rebuilt.

See symfony/symfony#16461 for details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants