Skip to content

Auto-wiring doesn't work #275

@alanondra

Description

@alanondra

Environment:

  • PHP: 8.4.11
  • Container: 5.1.0

Here's my container setup:

$providers = [
	// others
	new App\Providers\RoutingServiceProvider(),
];

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

$container->delegate(new League\Container\ReflectionContainer(
	cacheResolutions: false,
));

foreach ($providers as $provider) {
	$container->addServiceProvider($provider);
}

return $container;

I have a Service Provider mapping the League Router to the PSR-15 RequestHandler using a callback to configure it and load the routing table:

$this->container->addShared(Route\Router::class, fn () => $this->resolveRouter());
$this->container->addShared(RequestHandlerInterface::class, Route\Router::class);

Both class names are returned in provides().

And then in my application:

/**
 * Get the RequestHandler instance.
 *
 * @return \Psr\Http\Server\RequestHandlerInterface
 */
protected function getRequestHandler(): RequestHandlerInterface
{
	return $this->container->get(RequestHandlerInterface::class);
}

However, the resolveRouter method is never called (tested by putting die('test'); in the definition) unless explicitly called:

$this->container->addShared(Route\Router::class, fn () => $this->resolveRouter());
$this->container->addShared(RequestHandlerInterface::class, fn () => $this->container->get(Route\Router::class));

I was under the impression that mapping one class to another would have it look for the definition of the concrete class being passed and use that if it exists, instead of just creating a new blank instance.

As another example, I have an object that depends on a Context object for the constructor, which is manually inserted when instantiating the Container:

// container instantiation
$container->addShared(Context::class, $context);

// service provider
var_dump($this->container->get(Context::class)); // true
$this->container->addShared(Foo::class);

It never even attempts to resolve the Context, so when Foo is required it complains that no arguments were passed to the Foo constructor.

If I have to manually reconstruct something every time I need to add something to the Container it defeats the purpose of autowiring and DI in general, not only wasting my time but widening the surface vector for mistakes and adding redundancy, which means more potential points of failure if the way that dependency is defined changes in the future.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions