<https://lh3.googleusercontent.com/-MJQw2yspEUE/V_tt0Bg3xPI/AAAAAAAAB8s/Z6txSatzpM83T_v0AqUvcQXvgitUuzS1ACLcB/s1600/container_explanation.png>


<https://lh3.googleusercontent.com/-MJQw2yspEUE/V_tt0Bg3xPI/AAAAAAAAB8s/Z6txSatzpM83T_v0AqUvcQXvgitUuzS1ACLcB/s1600/container_explanation.png>

Hey,

Ok I spent the week-end trying to think about the pros and cons of this 
proposal.

@XedinUnknown, I'm not sure I understood 100% of your proposal so I'll try 
to rephrase it. If I'm wrong, let me know.

I understand you are trying to improve the "delegate lookup feature". Your 
goals are:

- to make it "explicit" that a container is implementing the "delegate 
lookup feature"
- to make it possible to nest containers at an unlimited level (to be able 
to nest a composite container in another composite container...)

To do so, you propose to add a new interface named 
ParentAwareContainerInterface 
<https://github.com/XedinUnknown/di/blob/master/src/ParentAwareContainerInterface.php>.
 
This interface is exposing a single method "getParentContainer()" that 
returns the parent container if any (i.e. the composite container 
containing this container).
When resolving a dependency, the container goes up the chain of parent 
containers 
<https://github.com/XedinUnknown/di/blob/master/src/AbstractParentAwareContainer.php#L39-L55>
 
until it reaches the root container. It uses the root container to look up 
any dependency (just like in the current delegate lookup feature).

Here are a few thoughts about this idea:

First: who is consuming the ParentAwareContainerInterface 
<https://github.com/XedinUnknown/di/blob/master/src/ParentAwareContainerInterface.php>?
 
This interface is consumed by "child" containers. If a container is a leaf 
in the container tree (so if it is not a composite container), then there 
is no need for it to implement the ParentAwareContainerInterface 
<https://github.com/XedinUnknown/di/blob/master/src/ParentAwareContainerInterface.php>.
 
The interface is trivial to implement and is a good declaration of intent 
(your container states it supports delegate lookup feature) but it is none 
the less useless. This interface is only useful for composite containers 
(so that they can also be bundled into parent composite containers).

Second, each container now needs to find the root container by going up the 
container tree. In your sample, you do this while resolving a service 
<https://github.com/XedinUnknown/di/blob/master/src/AbstractParentAwareContainer.php#L64>.
 
This is a bit of a problem performance-wise because this will slow service 
resolving (and this is a major no no for many implementors). Of course, 
there is a simple way around that. Finding the root container could be done 
only once, possibly in the constructor. This assumes that the parent 
container is passed to the child container constructor (or at build time). 
This also assumes that the parent container will never change in the life 
of a container (this is a safe assumption). Looking at @XedingUnknown code, 
this means that stuff like containers with mutable parents 
<https://github.com/XedinUnknown/di/blob/master/src/ContainerWithMutableParent.php>
 
should be forbidden and only containers with immutable parents 
<https://github.com/XedinUnknown/di/blob/master/src/ContainerWithImmutableParent.php>
 
should be allowed.

If we assume that the "parent" container is always passed to containers in 
their constructor, it means that containers MUST be constructed in the 
order of the tree (from top to bottom).


<https://lh3.googleusercontent.com/-MJQw2yspEUE/V_tt0Bg3xPI/AAAAAAAAB8s/Z6txSatzpM83T_v0AqUvcQXvgitUuzS1ACLcB/s1600/container_explanation.png>

<https://lh3.googleusercontent.com/-MJQw2yspEUE/V_tt0Bg3xPI/AAAAAAAAB8s/Z6txSatzpM83T_v0AqUvcQXvgitUuzS1ACLcB/s1600/container_explanation.png>

I made a picture so it would be more clear. If the "root container" exists 
before "Composite A" and if "Composite A" exists before "Container 1", then 
when "container 1" is created, instead of passing an instance of composite 
A, it should directly be passed an instance of the root container. That 
way, "container 1" does not have to go up the tree to find the root 
container. This makes the proposed "ParentAwareContainerInterface" useless, 
because finding the root container can be and should be done *before* the 
container is created.

@XedingUnknown, I understand your concerns that the "delegate lookup 
feature" of PSR-11 is not backed by a solid interface. After careful 
consideration, I'm not sure your proposal of adding a getter really solves 
any issues (because we already can nest several containers). However, you 
are making clear that we never spoke about the way containers should be 
created (and who should come first between the parent and the child 
container). After thinking about your proposal, what is now clear to me is 
that the parent should be created before the children (and maybe we should 
stress that out in the META document).

If I was to add another interface, it would more likely be a "container 
factory" (a la zend-expressive) that can create a container while passing 
the parent container in parameter:

interface ContainerFactoryInterface {
    // A composite container could use an array of 
ContainerFactoryInterface to build containers, passing them the very root 
container.
    public function createContainer(ContainerInterface $rootContainer);
}

@mnapoli, @mweierophinney, any thoughts about this? Do you think we need to 
consider this or am I overtinking things?

I think we also need to discuss more here the "delegate lookup feature". It 
is an optional feature, not backed by an interface and this is 
unprecedented in other PSRs (correct me if I'm wrong but I don't think 
other PSRs have similar optional features). To the rest of the members 
here, do you think we should do something special regarding this? 
Espceially, how should an implementing container advertise that it is 
supporting PSR-11 with/without delegate lookup feature?

Best regards,
David.


Le vendredi 7 octobre 2016 18:58:51 UTC+2, Xedin Unknown a écrit :
>
> Hi all,
>
> The delegate lookup feature of Container Interop didn't get as much 
> attention as I feel it deserves. Specifically, it is lacking formalization 
> in PHP - an interface. I started this conversation , but was instructed 
> that the mailing list is the better way to go.
> It seems that many would agree with me in that it would be great to have 
> the standard backed by an interface. There was talk of an interface 
> <https://github.com/container-interop/container-interop/pull/8>, but the 
> idea was shot down due to forcing the implementation to declare a setter. I 
> completely agree that forcing a setter is a bad idea.
> *But why not a getter?*
>
> * <https://github.com/XedinUnknown/di>*
> *XedinUnknown/di <https://github.com/XedinUnknown/di>* is an example of 
> an implementation that would achieve lookup delegation while depending on 
> one method of one interface. The rest is implementation details.
> In short, the container that wishes to delegate must pass its parent (or, 
> in my implementation, the "root" parent), if set, to the service definition 
> callable. If the callable is a composite container, it will forward the 
> call to the first child container that contains the definition. Please find 
> a more expanded description in the repo's Readme.
>
> Looking forward to your comments, questions, or suggestions.
>

-- 
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+unsubscr...@googlegroups.com.
To post to this group, send email to php-fig@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/0f7ffad2-f50c-4255-a5c2-2640d9bab493%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to