container-interop / definition-interop

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

Facultative definitions #21

Closed Anahkiasen closed 8 years ago

Anahkiasen commented 8 years ago

This is something I was about to create an issue for but was reminded by #16. I think we need a way to declare a definition as "facultative" – ie, if there is already something in the container for that identifier, don't overwrite it. A definition that is more there as a fallback in case the user doesn't provide anything for it.

For this I had two solutions in mind:

  1. Create a class which can wrap any definition
  2. Add a flag to all definitions

Examples:

class SomeDefinition implements DefinitionProviderInterface
{
    public function getDefinitions()
    {
        // Solution 1
        $logger = new ObjectDefinition(Monolog::class);
        $logger = new FacultativeDefinition($logger);

        // Solution 2
        $logger = new ObjectDefinition(Monolog::class);
        $logger->setFacultative();

        // My package that needs a logger
        $package = new ObjectDefinition(MyPackage::class);
        $package->setConstructorArguments(new Reference(LoggerInterface::class));

        return [
            LoggerInterface::class => $logger,
            'package' => $package,
        ];
    }
}

What do you think?

Anahkiasen commented 8 years ago

First solution is easier to type hint and check for but harder to handle, second solution is easier to handle but kind of "hidden" away.

mnapoli commented 8 years ago

Do you have use cases for this? Something else I'd also consider is whether it's possible in Symfony? This is the framework with (by far) the most modules, if they managed to do it without it that's a sign it's not necessary.

Anahkiasen commented 8 years ago

Something else I'd also consider is whether it's possible in Symfony?

I don't think this is something you'll see in Symfony because this is something more commonly found in agnostic packages, which cannot be used on Symfony because of how tied to SF the bundles ares.

But typically the use case can be any agnostic package, imagine you need a PSR-X implementation, you provide one in your definition/SP/whatever so that your package can work standalone. But ideally if your definition were to be added on a container, you wouldn't want to override anything the user has already set. If my package provides Monolog as default logger but the user picked a different one, I don't want to override the user's LoggerInterface implementation with mine when the definition gets resolved.

Anahkiasen commented 8 years ago

This is not a priority by the way, just something I thought we'd need to discuss but nothing major.

mnapoli commented 8 years ago

Oh ok user config has to override framework and bundle config, without that I don't see how you can build something useful.

Anahkiasen commented 8 years ago

Yeah you know what the more I think about this idea the more I think it should either be dealt with by the user or the container. It was originally based on illuminate container's bindIf which only binds an entry if there is nothing there already, but on further reflection this can already be easily reproduced in other ways and I don't really like either of the two solutions I suggested.

Gonna close this for now.