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.
