Question: How to achieve autowiring inside the service provider?
creative-andrew opened this issue · comments
Andres commented
Hello
Based on your example of the register
method of the service provider, we need to explicitly define dependencies/arguments to add the class to the container.
public function provides(string $id): bool
{
$services = [
Some\Controller::class, // class with Request and Model as dependencies.
];
return in_array($id, $services);
}
public function register(): void
{
$this->getContainer()->add('key', 'value');
$this->getContainer()
->add(Some\Controller::class)
->addArgument(Some\Request::class)
->addArgument(Some\Model::class)
}
I was wondering if it is possible to just add the class provided in the services array and let the container resolve/auto-wire. Namely, to be able to just do the following:
public function register(): void
{
$this->getContainer()
->add(Some\Controller::class)
}
I am trying to make the container call a method init
on all the services defined within the service provider. For example:
Container:
final class Container {
private $service_providers = [
TestServiceProvider::class
];
private $container;
public function __construct() {
$this->container = new LeageContainer();
$this->container->delegate(
new ReflectionContainer()
);
foreach ($this->service_providers as $service_provider_class) {
$service_provider = new $service_provider_class();
$this->container->addServiceProvider($service_provider);
foreach ($service_provider->getServices() as $service) {
$this->container->get($service)->init();
}
}
}
...
}
ServiceProvider
class TestServiceProvider extends AbstractServiceProvider {
private $current_service_being_procces = '';
private $services = [
TestService::class => TestService::class,
];
public function getServices() {
return $this->services;
}
public function provides(string $id): bool {
if (isset($this->getServices()[$id])) {
$this->current_service = $this->getServices()[$id];
return true;
}
return false;
}
public function register(): void {
$this->getContainer()->add($this->current_service);
}
}
TestService:
class TestService {
public function __construct(TestService2 $testService2) {
$this->testService2 = $testService2;
}
public function init() {
echo "hi";
$this->testService2->bye();
}
}
$container = (new Container());
Fatal error: Uncaught ArgumentCountError: Too few arguments to function \Container\ServiceProvider\TestService::__construct(), 0 passed and exactly 1 expected