Thanks, David. My main concern is that as presented the delegate
feature is not really a feature, more a "by the way, here's this cool
thing you can do." The composite container isn't defined at all, and as
you note the question of what happens when the delegate container has
its own services is also completely undefined. Yet that is a valid use
case, and in fact the main one that I'd see being useful: Allowing a
library to provide its own mini-container for its services, which then
simplifies adding a large and more complex library (Doctrine, Guzzle,
etc.) to an application without the need for a custom bridge
module/bundle/whatever.
It may be that case is better handled through the forthcoming container
registration spec. If that's the case, then I see insufficient reason
to include DDL here. If it is kept, it needs to be considerably
overhauled to clarify those many edge cases, and suggest, well, what if
anything would be more than a "by the way, this quirk would be
possible."
One or the other: Remove, or revamp to be more clear and useful.
--
Larry Garfield
la...@garfieldtech.com
> > <
https://www.thecodingmachine.com/psr-11-an-in-depth-view-at-the-delegate-lookup-feature/>
> > )
> >
> > *What is it?*
> >
> > The *delegate dependency lookup feature* (let's call it DDL) is a *design
> > pattern.*
> > It is the only way we have found to compose containers.
> >
> > *What problem does it solve?*
> >
> > Let's admit you want to compose/chain containers (more on why you might
> > want to do this later).
> > To do this, you would typically use a "CompositeContainer
> > <
https://github.com/jeremeamia/acclimate-container/blob/master/src/CompositeContainer.php>"
> > (a container without any entry whose role is to ask each "child" container
> > in turn "do you contain the entry I'm looking for?")
> >
> > [image: composite.png]
> >
> > The CompositeContainer is not enough. Let's admit container 1 contains
> > your controller. You fetch your controller. Your controller has a
> > dependency on your ORM's entity manager. If the entity manager is part of
> > container 2, container 1 will be unable to fetch it (because internally, it
> > will perform a call "$this->get()" to fetch the entityManager dependency.
> > Similarly, the entityManager should be able to fetch a dependency (for
> > instance the dbConnection) inside another container...
> >
> > The delegate lookup feature simply states that containers should not fetch
> > their dependencies locally, but instead, they should fetch their
> > dependencies from the top-most container (in this example, this is the
> > CompositeContainer).
> >
> > In our example, this would go like this:
> >
> > - The framework asks for the "controller" entry to the CompositeContainer
> > - The CompositeContainer asks Container 1: "do you have "Controller".
> > Container 1 answers yes
> > - The CompositeContainer asks Container 1: "give me "Controller".
> > - Container 1 needs to fetch the "EntityManager" dependency, so Container
> > 1 calls *$compositeContainer->get('EntityManager')*; (here! container 1
> > is "delegating" the dependency lookup to the composite container)
> > - The CompositeContainer asks Container 1: "do you have "EntityManager"?
> > => response is no.
> > - The CompositeContainer asks Container 2: "do you have "EntityManager"?
> > => response is yes. The CompositeContainer asks Container 2: "give me
> > "EntityManager".
> > - ... and do on
> >
> >
> > *Do we want this?*
> >
> > To be honest, PSR-11 is already useful without the DDL feature. The
> > ContainerInterface is enough to allow users to swap container
> > implementations.
> >
> > Being able to compose containers is a nice feature, but it's optional.
> > PSR-11 can be useful without DDL.
> >
> > *What are valid use cases for this?*
> > *By the way, what is the real performance impact of using a
> > CompositeContainer and DDL?*
> >
> > I've been doing some tests using a modified version of Symfony.
> > You can read my old article about the performance impact on DDL here
> > <
https://www.thecodingmachine.com/psr-11-performance-impact-of-the-delegate-lookup-feature/>.
> > Spoiler alert: impact is quite low, I was not able to measure it.
> >
> >
> > *How do we implement this?*
> >
> > DDL support is quite easy to add in any container out there. From my
> > experience with container-interop, I've never seen a case where it took
> > more than a few lines of code to add support.
> >
> > Typical implementation goes like this:
> >
> > 1- You modify the constructor to accept an additional parameter: the root
> > container. This parameter is optional. If not passed, the root container is
> > the container itself.
> >
> > So your container constructor now looks like this:
> >
> > public function __construct($param1, $param2, ..., ContainerInterface
> > $rootContainer = null) {
> > ...
> > $this->rootContainer = $rootContainer ?: $this;
> > }
> >
> > In your container code, when you perform a call to get on a dependency,
> > instead of calling $this->get, you call $this->rootContainer->get.
> >
> > Aaaaaand you're done :)
> >
> > *Important*: As you can see, if you are not using a composite container,
> > the impact on performance of a container is null (it is almost the same
> > code executed). So a container can add support for DDL without impacting
> > its average performance.
> >
> > *Is it used somewhere?*
> >
> > The ContainerInterface has been mostly designed by looking at what common
> > methods were supported by containers out there.
> > On the contrary, the dependency delegate lookup design pattern has been
> > "invented" by container-interop and does not stem from previous work from
> > one container or another. This is of course to be expected, because without
> > the ContainerInterface, it is not possible to envision composing containers.
> >
> > The delegate dependency lookup feature is already supported by a number of
> > containers out there (see:
> >
https://github.com/container-interop/container-interop#projects-implementing-the-delegate-lookup-feature
> > )
> >
> > I don't know if it is wildly used or not, but I know at least one place
> > where this was useful to me: the laravel <=>
> > container-interop/service-provider bridge
> > <
https://github.com/thecodingmachine/laravel-universal-service-provider/>.
> > I used it here to add support for container-interop's service providers
> > <
https://github.com/container-interop/service-provider> into Laravel.
> > Rather than forking Laravel container to add support for service providers
> > in it, I decided to add another container (Simplex) that already had
> > support for service providers next to Laravel's one.
> >
> >
> > *Summary:*
> >
> > Is it essential to PSR-11? No
> > Is it useful? Yes, in some specific cases (I do not expect it to be wildly
> > used)
> > Is it easy to implement? Dead easy
> > Does it have an impact on performance? No if only one container is used
> > (business as usual), yes if many containers are used (but this is to be
> > expected)
> >
> > Should it be part of the PSR?
> >
> > My personal opinion is yes. It does not hurt, it is optional, it is the
> > only way we could put containers side-by-side and let them share entries. I
> > believe advertising this design pattern in the PSR will make it more wildly
> > adopted. This, in turn, will increase framework interoperability.
> >
> > Note: there are a ton of things I would still like to discuss, like "can a
> > composite container contain entries?" or "can I nest composite
> > containers?". Also, @crell asked a lot of questions in his initial review
> > and I'm only surfacing a few answers but I'm afraid that will get too
> > tricky quickly, so I'm going to stop there for the time being. :)
> >
> > But here is the real question: do you think DDL is useful, and do you
> > think it should be part of PSR-11?
> >
> > Best regards,
> > David.
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to
php-fig+u...@googlegroups.com.
> To post to this group, send email to
php...@googlegroups.com.
> To view this discussion on the web visit
>
https://groups.google.com/d/msgid/php-fig/273f0df4-ee6b-4712-b550-4609fb515ec6%40googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.