Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FactoryInterface::make with parameters on reference definitions #771

Open
hultberg opened this issue Apr 12, 2021 · 0 comments
Open

FactoryInterface::make with parameters on reference definitions #771

hultberg opened this issue Apr 12, 2021 · 0 comments

Comments

@hultberg
Copy link

I noticed that when you call FactoryInterface::make() with a definition and parameters that is a reference to another definition FactoryInterface::make will end up calling ContainerInterface::get() on the target entry name since \DI\Definition\Reference::resolve is called.

Consider the following example.

<?php
declare(strict_types=1);

namespace TestApp {

    require './vendor/autoload.php';

    interface ConnectionInterface
    {
    }

    class Connection implements ConnectionInterface
    {
        public string $host;

        public function __construct(string $host)
        {
            $this->host = $host;
        }
    }

    $containerBuilder = new \DI\ContainerBuilder();
    $containerBuilder->addDefinitions([
        \TestApp\ConnectionInterface::class => \DI\get(\TestApp\Connection::class),
        \TestApp\Connection::class => \DI\factory(static function () {
            return new \TestApp\Connection('localhost.master');
        }),
    ]);

    $container = $containerBuilder->build();

    $container->get(\TestApp\ConnectionInterface::class);
    $container->get(\TestApp\Connection::class);

    echo $container->make(\TestApp\ConnectionInterface::class, ['host' => 'localhost.read'])->host . PHP_EOL; // localhost.master
    echo $container->make(\TestApp\Connection::class, ['host' => 'localhost.read'])->host; // localhost.read
}

Is this intentional? FactoryInterface::make is documented to always resolve the definition which always lead to a new instance to be created (if the definition creates objects) except for Reference definition.

One fix is to call make with the abstract class. In my real world example I use FactoryInterface::make in my custom RepositoryFasctory for doctrine entities and I use interfaces for my custom repositories. The repositories using interfaces then get the wrong EntityManager instance since I send the correct EntityManagerInterface as a parameter to FactoryInterface::make.

Thanks in advance for help and guidance. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant