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

[Question/suggestion] Not possible to supply/override services using the type names in $parameters #895

Open
dakujem opened this issue Sep 4, 2024 · 0 comments

Comments

@dakujem
Copy link

dakujem commented Sep 4, 2024

I made this 3 line alteration of the ParameterResolver in PHP-DI v6.4 (sorry, legacy project).
image

I made the change so that I could be able to swap the following code

use DI\FactoryInterface;

        $factory = $container->get(FactoryInterface::class);
        $component = $factory->make(MainComponent::class, [
            'request' => $request,
        ]);

to this code, which fits better to the overall usage of the container, since every other service fetching is done through class names (preferably interfaces)

use DI\FactoryInterface;
use Psr\Http\Message\ServerRequestInterface as Request;

        $factory = $container->get(FactoryInterface::class);
        $component = $factory->make(MainComponent::class, [
            Request::class => $request, // <--- the difference is here
        ]);

If it is not clear, the code provides/overrides a service using class name instead of parameter name.

I wonder ... why has this not been incorporated into PHP-DI container? It is very hard to replace this particular part, because the ResolverDispatcher is tightly coupled to the Container class which uses private props, and as such one would need to override half of the container class to replace it.

BTW, the same goes for the invoker, so If one desires to tweak the ResolverChain used for parameter resolution in the Container::call method, one would have to override much more than just a couple lines of code.

So my primary question is this:
Is it by design that it is not possible to supply or override selected services using the type names when making calls to make or get?

I'm actually using my own autowiring solution with a simple container proxy just to overcome this shortcoming of PHP-DI container, but i may be missing something.

final class ContainerProxy implements ContainerInterface
{
    use StrictAccess;

    private ContainerInterface $container;
    private array $overrides;

    public function __construct(ContainerInterface $container, array $overrides)
    {
        $this->container = $container;
        $this->overrides = $overrides;
    }

    public function has($id): bool
    {
        return isset($this->overrides[$id]) || $this->container->has($id);
    }

    public function get($id)
    {
        $getter = $this->overrides[$id] ?? fn() => $this->container->get($id);
        return $getter($this->container, $id);
    }
}

// used like this:
        $serviceOverrides = [];
        $serviceOverrides[QueueDispatcher::class] = function (ContainerInterface $c) use ($runtime) {
            return $c->get(QueueDispatcher::class)->withSomeSetting('tweaked-value');
        };
        $containerProxy = new ContainerProxy($this->container, $serviceOverrides);
        $result = (new Genie($containerProxy))->invoke($callable);
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