container-interop / definition-interop

[EXPERIMENTAL] Promoting container interoperability through standard definitions
MIT License
19 stars 2 forks source link

Adding the possibility to make a reference "optional" #25

Open moufmouf opened 8 years ago

moufmouf commented 8 years ago

I've been playing quite a bit with definition-interop, and I realized one small addition could be really useful: the ability to have "optional" references.

The whole idea is that a service could reference a container entry if it exists, or fallback to "null" if the container entry does not exist.

This can be useful in a number of cases. For instance, a service could try to access the "debug" ParameterDefinition (that is a boolean saying whether we are in debug mode or not). If the user did not set up a "debug" ParameterDefinition, rather than throwing an error, we could simply fall back to "null".

That could work this way:

$service = new InstanceDefinition('\My\Router');
// The second argument of Reference constructor says the reference is optional
$service->addConstructorArguments(new Reference('debug', true));

Now, when we resolve the service, if there is no "debug" entry in the container, null is passed.

In the ReferenceInterface, we just have to add a method:

/**
 * Returns whether the reference is optional.
 * When a reference is optional, if the target does not exist, the reference is ignored and no exception is thrown.
 * @return boolean
 */
function isOptional();

This is somewhat trivial to implement in most of the containers out there (can be done at resolve time).

Also, this notion of optional references is supported by Symfony: http://symfony.com/doc/current/book/service_container.html#making-references-optional

Finally, by combining optional references with factories, it should be possible to solve #21 (i.e. use one service if it is defined, and another service otherwise)

mnapoli commented 8 years ago

I see the use case but I'm a bit careful before adding new features. I'm sure it's not supported by all containers, we have to be careful before expecting too much.

Related: is it a best practice for modules to depend on "global" entries (e.g. debug). Wouldn't it be better that it depended on my_module.debug which would be an alias to (for example) debug. But yeah the alias would have to have a default value so back to square one…

moufmouf commented 8 years ago

Yep, totally agree that depending on my_module.debug is a better strategy. Don't know why I didn't think about it sooner. Anyway, as you say, this has to be an alias, so we are back to square one.

Shall we keep this issue open as a reference for future possible features? Maybe we shall start adding labels and milestones to these issues?

mnapoli commented 8 years ago

Why not add labels indeed. Maybe this is the kind of topic on which we would move forward much more easily when discussing it live, let's discuss that this saturday (link for everyone else interested: https://groups.google.com/d/msg/php-fig/wQuVK2SXYkk/p6w1sMxSCgAJ).