-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DependencyInjection] allows references to be declared as "lazy" #6140
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
In contrast to regular references, a lazy references is not guaranteed to be fully initialized upon injection, but may instead be lazy initialized when it is first accessed by the consuming service. Lazy makes no implementation restrictions on how those referenced services are to be constructed but leave this up to a concrete implementor.
@@ -25,6 +25,7 @@ | |||
* XmlFileLoader loads XML files service definitions. | |||
* | |||
* @author Fabien Potencier <fabien@symfony.com> | |||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
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.
why ?
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 thought I was going to change the file, and saw that I had not yet added my name :) Anyway, I have made many small feature additions in this file that should warrant the tag.
If possible, I'd like to first talk about the general idea of this patch though. If we agree on that, we can also talk about when @author tags are justified, and whether this one (or others) need to be removed.
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 was just curious, sorry for that
Maybe the |
@schmittjoh do you think tests for lazy services should reside in core? |
@schmittjoh is it meant to be used for #5012 or is it totally unrelated ? |
@stof, that is what it would be used for. |
This seems to be useful for #6102 as well. Regarding the patch; seems strict was partly there from before, but not covered by tests. Elsewhere, or should it be added? |
Yes, there were a few bugs I noticed when adding lazy. Regarding #6102, you might want to look at http://jmsyst.com/bundles/JMSDiExtraBundle/master/lazy_service_collections. You already should have that capability if you are using the Symfony Standard Edition. |
Closing as the discussion should now happen on #7527 |
This PR was squashed before being merged into the master branch (closes #7890). Discussion ---------- ProxyManager Bridge As of @beberlei's suggestion, I re-implemented #7527 as a new bridge to avoid possible hidden dependencies. Everything is like #7527 except that the new namespace (and possibly package/subtree split) `Symfony\Bridge\ProxyManager` is introduced | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #6140 (supersedes) #5012 #6102 (maybe) #7527 (supersedes) | License | MIT (attached code) - BSD-3-Clause (transitive dependency) | Doc PR | Please pester me to death so I do it This PR introduces lazy services along the lines of zendframework/zendframework#4146 It introduces an **OPTIONAL** dependency to [ProxyManager](https://github.com/Ocramius/ProxyManager) and transitively to [`"zendframework/zend-code": "2.*"`](https://github.com/zendframework/zf2/tree/master/library/Zend/Code). ## Lazy services: why? A comprehensive example For those who don't know what this is about, here's an example. Assuming you have a service class like following: ```php class MySuperSlowClass { public function __construct() { // inject large object graph or do heavy computation sleep(10); } public function doFoo() { echo 'Foo!'; } } ``` The DIC will hang for 10 seconds when calling: ```php $container->get('my_super_slow_class'); ``` With this PR, this can be avoided, and the following call will return a proxy immediately. ```php $container->getDefinitions('my_super_slow_class')->setLazy(true); $service = $container->get('my_super_slow_class'); ``` The 10 seconds wait time will be delayed until the object is actually used: ```php $service->doFoo(); // wait 10 seconds, then 'Foo!' ``` A more extensive description of the functionality can be found [here](https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md). ## When do we need it? Lazy services can be used to optimize the dependency graph in cases like: * Webservice endpoints * Db connections * Objects that cause I/O in general * Large dependency graphs that are not always used This could also help in reducing excessive service location usage as I've explained [here](http://ocramius.github.com/blog/zf2-and-symfony-service-proxies-with-doctrine-proxies/). ## Implementation quirks of this PR There's a couple of quirks in the implementation: * `Symfony\Component\DependencyInjection\CompilerBuilder#createService` is now public because of the limitations of PHP 5.3 * `Symfony\Component\DependencyInjection\Dumper\PhpDumper` now with extra mess! * The proxies are dumped at the end of compiled containers, therefore the container class is not PSR compliant anymore Commits ------- 78e3710 ProxyManager Bridge
I had written this patch during sflive Berlin. It allows to store additional metadata in references. It contains no code to leverage that additional metadata though.
Code that uses the lazy attribute could also reside outside of the core repository as it might contain additional dependencies which we probably do not want in the core component.