thephpleague / container

Small but powerful dependency injection container

Home Page:http://container.thephpleague.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Auto wiring a shared dependency

jtojnar opened this issue · comments

I tried using ReflectionDelegate to achieve auto-wiring and it works mostly great. The issue occurs when I register some services as shared – then they won’t be autowired any more.

See the following simplified example:

<?php

require __DIR__ . '/vendor/autoload.php';

class Logger {
    public function __construct(string $name) { }
}

class Authentication {
    public function __construct(Logger $logger) { }
}

class AboutController {
    public function __construct(Authentication $authentication) { }
}

$container = new League\Container\Container();

// Register the reflection container as a delegate to enable auto wiring.
$container->delegate(new League\Container\ReflectionContainer(true));

$container
    ->add(Authentication::class)
    ->setShared()
;

$container
    ->add(Logger::class)
    ->addArgument('selfoss')
    ->setShared()
;

var_dump($container->get(AboutController::class));
Fatal error: Uncaught ArgumentCountError: Too few arguments to function Authentication::__construct(), 0 passed and exactly 1 expected in test.php:10
Stack trace:
#0 [internal function]: Authentication->__construct()
#1 src/Definition/Definition.php(212): ReflectionClass->newInstanceArgs(Array)
#2 src/Definition/Definition.php(175): League\Container\Definition\Definition->resolveClass('Authentication')
#3 src/Definition/Definition.php(154): League\Container\Definition\Definition->resolveNew()
#4 src/Definition/DefinitionAggregate.php(79): League\Container\Definition\Definition->resolve()
#5 src/Container.php(175): League\Container\Definition\DefinitionAggregate->resolve('Authentication')
#6 src/Container.php(118): League\Container\Container->resolve('Authentication')
#7 src/Argument/ArgumentResolverTrait.php(45): League\Container\Container->get('Authentication')
#8 src/Argument/ArgumentResolverTrait.php(107): League\Container\ReflectionContainer->resolveArguments(Array)
#9 src/ReflectionContainer.php(58): League\Container\ReflectionContainer->reflectArguments(Object(ReflectionMethod), Array)
#10 src/Container.php(203): League\Container\ReflectionContainer->get('AboutController')
#11 src/Container.php(118): League\Container\Container->resolve('AboutController')
#12 test.php(33): League\Container\Container->get('AboutController')
#13 {main}
  thrown in test.php on line 10

I could addArguments the dependencies explicitly but doing it for all of the shared services would be annoying.