This is a continuation from the discussion about whether PSR-11 containers 
should always return the same instance.
See https://groups.google.com/forum/#!topic/php-fig/L8rDUwRFsOU for the 
beginning of the discussion.

<TL;DR;> I believe that we should keep the SHOULD word in place because it 
does not hurt in practice and because we can require a container to always 
return the same instance in the yet to come PSR that will define how we put 
things into a container (see container-interop/service-provider 
<https://github.com/container-interop/service-provider/> for a proposal). 
On the other hand, requiring the container to return always the same value 
would make PSR-11 de-facto incompatible with most containers out there (so 
should be avoided). However, I think we definitely need to make 
improvements on the wording that is clumsy (see end of the message). 
</TL;DR;>

Currently, the spec says:


*Two successive calls to get with the same identifier SHOULD return the 
same value. However, depending on the implementor design 
and/or user configuration, different values might be returned, 
so user SHOULD NOT rely on getting the same value on 2 successive calls.  *

Hari, Larry, Pedro are asking if we could strengthen the SHOULD to a MUST 
(as in: *Two successive calls to get with the same identifier MUST return 
the same value*).

For instance, Larry says:

> I would prefer to have get() defined to always return the same object 
(lazy loaded or otherwise, not relevant here), as that is the typical case, 
and another method added (either on the same interface or a separate one, I 
am flexible) to handle the factory use case.  That way I know the behavior 
of each object I get back, specifically in relation to whether I have a 
private copy or not.

First of all, let me say if I was starting from a blank slate, I would 
definitely agree with you and put a MUST here. But we are not starting from 
a blank slate and many containers out there offer the possibility to create 
new services each time you call "get". For instance Pimple (with the 
factory method), or Symfony (with the "shared" option: 
http://symfony.com/doc/current/service_container/shared.html)
I definitely want Pimple and Symfony in PSR-11 (or at least I want to be 
able to create an adapter for those) and putting a "MUST" in the 
requirements makes this impossible. So if we decide to force containers to 
always return the same value, we'd better have a very good reason to do so.

Now, what is the real impact of this?

You all seem to imply that if we don't put a "MUST" here, then we cannot 
"trust" the container to give us a usable instance. The container might be 
"vicious" and decide to fool its user by giving him a new instance while 
the user was expecting the same instance. But this is not how it works. The 
typical use case for ContainerInterface is to allow a consumer (like a 
router) to be "container agnostic". As a user, I can decide to plug any 
container to a given router. The router will then be able to fetch the 
correct controller (or the correct action if you do ADR) based on the 
controller name. In this scenario, the user is the one in charge of 
configuring the container (and putting the controller in the container). If 
the user decides that he wants to use a container that can act as a factory 
and that he wants to configure some services that are created on each 
request, it is his responsibility. Keep in mind that since we do not 
standardize how to put things in the container, it has to be the user 
responsibility to configure his container.

So saying that a container MUST return always the same instance is 
premature. When we will start to standardize how to put things in a 
container, then we can define that configured instances MUST be the same. 
But we can do this in the next PSR (the one that defines how to put things 
into a container) and not in this one.


Now, even if I'm really convinced that we should keep the "SHOULD" in 
place, I understand from the numerous comments that the way the spec is 
written is clumsy (or rather worrisome).

Why did I propose this sentence in the first place? I was thinking that a 
"CompositeContainer" could try to cache in an array the list of services 
already fetched from its children. This is something you can do if you know 
the children containers will always return the same instance but that you 
cannot do if you don't know if the container will return the same or a new 
instance. So really, the "SHOULD" prevents us to write composite containers 
that "cache" the result from children. This is actually not a very big 
deal, as composite containers are very seldomly used. What I was trying to 
say here was: "Hey, don't cache the services returned by a container, it 
might return a new instance on the next call". I proposed this wording 2 
years ago in container-interop. In hindsight, this is certainly too 
specific to be part of a PSR.

I see 3 possible solutions to replace this:

*Solution 1*:
Let's completely drop the 2 sentences => PSR-11 does not address whether a 
container should return the same instance or not (this is something we can 
deal with when we define how to put things into a container)

*Solution 2*:
Let's only keep the first sentence: *Two successive calls to get with the 
same identifier SHOULD return the same value.*

*Solution 3*:
Let's rewrite the second sentence: *Two successive calls to get with the 
same identifier SHOULD return the same value. A container MAY offer the 
possibility to return a new value for some identifiers if the user 
configured it accordingly.*
(The wording of solution 3 should be improved but you get the idea)

@larry, @hari, @pedro: do you favor one of those solutions or do you still 
think we should use a "MUST" in the spec?
@matthieu, @mathew: any preference regarding the solutions proposed above?

We should also try to ping more container authors to get their advice on 
this issue. I'd be interested in knowing what Fabien Potencier or Taylor 
Otwell think about this.

++
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/1265a421-0903-4295-8638-0c4d0336876c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to