container icon indicating copy to clipboard operation
container copied to clipboard

Question: Why there is no set method?

Open tbreuss opened this issue 3 years ago • 7 comments

Why doesn't the interface provide a "set" method? I wonder what the use case for the interface is if I can't rely on a contract about how objects can be stored in the container?

See similar question on SO at https://stackoverflow.com/q/61504435/6161354.

Thanks for clarifying.

tbreuss avatar Nov 03 '22 21:11 tbreuss

Hi, this is explained in this document here: https://www.php-fig.org/psr/psr-11/meta/#31-goals

Hope that answers your question!

mnapoli avatar Nov 03 '22 21:11 mnapoli

Thanks for clarifying and sorry for the rtfm thing. I had a different expectation and simply was surprised that the set method is not included.

In simplified terms, could one say that the target audience for the container interface are authors of libraries or frameworks and not authors of concrete applications where the application itself is responsible for filling the container?

tbreuss avatar Nov 04 '22 07:11 tbreuss

Exactly yes.

mnapoli avatar Nov 04 '22 09:11 mnapoli

Not so nice. What about a framework building dev? Perhaps we want to swap the Di too? :)

Simple example:

$config = [
    // ...
    'di'          => [
        // class: MUST implement a \Psr\Container\ContainerInterface.
        # DISABLED - buggy. Using Awesome Di now.
        # 'class' => \Foo\Bar\Di::class,
        'class'   => \Awesome\Di::class,
        'options' => [
            // ...
        ],
    ],
    'cache'       => [
        'class'        => \Foo\Bar\Cache::class,
        'options'      => [
            // ...
        ],
        'is_singleton' => true,
    ],
    'http_client' => [
        'class'        => \Foo\Bar\Http\Client::class,
        'options'      => [
            // ...
        ],
        'is_singleton' => false,
    ],
];

class App
{
    /**
     * @var \Psr\Container\ContainerInterface
     */
    protected $di;

    /**
     * @param array $config
     */
    public function __construct(array $config)
    {
        // Set app di.
        $class = $config['di']['class'];
        $options = $config['di']['options'];
        $this->setDi(new $class($options));

        // Set cache on di.
        $lazyLoadCallable = function () use ($config) {
            $class = $config['cache']['class'];
            $options = $config['cache']['options'];
            return new $class($options);
        };
        $this->getDi()->setSingleton($lazyLoadCallable);
        // or
        // $this->getDi()->setShared($lazyLoadCallable);
        // or
        // $shared = true;
        // $this->getDi()->set($lazyLoadCallable, $shared);
        // or
        // $shared = true;
        // $lazy = true;
        // $this->getDi()->set([$class, $options], $shared, $lazy);

        // Set http client on di.
        $class = $config['http_client']['class'];
        $options = $config['http_client']['options'];
        $shared = false;
        $lazy = true;
        $this->getDi()->set([$class, $options], $shared, $lazy);
    }

    /**
     * @param \Psr\Container\ContainerInterface $di
     *
     * @return App
     */
    public function setDi(\Psr\Container\ContainerInterface $di): App
    {
        $this->di = $di;
        return $this;
    }

    /**
     * @return \Psr\Container\ContainerInterface
     */
    public function getDi(): \Psr\Container\ContainerInterface
    {
        return $this->di;
    }
}

Perhaps we can get a \Psr\Container\Dependency\Injection\DiInterface ?

cottton avatar Jan 28 '23 15:01 cottton

@cottton this would be a separate PSR, I don't think it's worth discussing here because this PSR is not about that. It will never happen in this PSR specifically.

mnapoli avatar Jan 28 '23 17:01 mnapoli

Is a standard for DI configuration worked on? To find the best implementation you now have to learn how each package works. A common setup syntax would fix that.

robopzet avatar Feb 16 '23 15:02 robopzet

With my own framework I simply extended pimple but created a RegistrationInterface with a method public function addToContainer(Container $c): void;, I call it Barnacle because it's stuck to a lot of my code until there's something that deals with this in a better way https://github.com/delboy1978uk/barnacle/blob/master/src/RegistrationInterface.php

delboy1978uk avatar Feb 08 '24 21:02 delboy1978uk