Conversation
Conflicts: src/DI/Container.php src/DI/Definition/Resolver/FactoryDefinitionResolver.php tests/IntegrationTests/DI/InjectionTest.php tests/UnitTests/DI/ContainerBuilderTest.php
|
Would this allow for compiler passes like in Symfony? The main use case that I'm interested is that you could tag several services and then add them all to another class. Really like the look of 4.0 and enjoyed your blog post about it. Makes a lot of sense. Keep up the great work! |
@polothy Right now this doesn't support compiler passes. Maybe it should, that's a great idea. However, regarding tagged services, I am not convinced that this would be the best solution. I'd rather see a feature in the container than in the compiler only. Symfony's container works only when compiled (or at least tagged services). PHP-DI is supposed to work without being compiled. I am sure we can find a great solution for "tagged services" that would work not compiled and that would be overridable and extensible. The way I have used (and seen used) tagged services is only to inject collections of services/objects. I.e., most of the time, it is to call a
Thank you! |
|
Hi! What if I have much amount of classes loaded by reflection definition source? Can they be compiled? |
|
@m00t Yes. Every definition that is not directly set on the container (i.e. So reflection, annotation or explicit definition: no difference in performance. |
|
Cool! Do you have any estimates when it will be tagged? |
@mnapoli Yes, this is the main use case for me at least. I was also using a configurator, but I don't think that needs to necessarily be handled by PHP-DI. Would it be possible to tell PHP-DI to inject all instances of Foo into something? Or for each Foo, call setFoo? Perhaps that could be too greedy at times, hrm. |
|
@m00t I am working on benchmarking this to "prove" it improves performances. But it turns out it's really hard :/ because:
So no real estimate, however I'll be working on this in the next weeks to have it in 4.1. @polothy Yes that's what I'm thinking about. Maybe some way of defining a "collection" (≠ "object" or "value"), and injecting a collection in a method either by calling it once with an array, or calling it several times.
yeah that could be a problem, especially if you have several decoupled modules (or bundles f.e.), you might want to:
|
@mnapoli Hrm, yeah interesting. Each could have a collection of Foos that they have implemented and need to use. But I wouldn't want Module X to get Module Y's Foos (If that makes sense haha). But at a higher level, I may want all instances of Bars from every module. |
|
What if make compilation process more symfony-di way: lets compile one huge file and then just use it. It should eliminate all IO problems I think |
|
@m00t The problem is with autowiring or annotation, the container has no way of knowing which classes will ever be asked. In Symfony, all definitions are explicitely written down, so the container knows what to compile. In the solution implemented in this PR, each definition is compiled to a separate file. I think it shouldn't make a lot of difference with an Opcache anyway, but it's hard to test that. |
|
@mnapoli Take a look at zend-di, it scans all directory with sources and create definitions for classes, and then they can be dumped to one huge container |
|
@m00t Interesting. I wonder though how it decides which classes might ever be injected. Or does it try to detect calls to |
|
@mnapoli I think it doesnt try to detect them, just dump definitions for all found classes |
|
@mnapoli I created some simple proof of concept for one-huge-container-file-compiler. Please, take a look if you are interested in: https://github.com/m00t/php-di-compiler-poc |
|
@m00t Neat! This is very interesting, if you have time feel free to work on a PR, else I'll look into that in the next weeks. |
|
@mnapoli I will try my best, but can not promise that I will do that |
Compile the container to PHP code for best performances.
TODO:
What would also be needed:
Container::set()) -> dynamic shouldn't be compiledAlso instead of maintaining 2 ways of resolving definitions (DefinitionResolver and DefinitionCompiler), it might be easier to just
eval()the code generated by the compiler on the fly. This generated code can be cached as definitions are cached today. I think it would be even faster than today.I did mess some things up with git, I should have put some commits in the 4.0 branch instead of this one :/