Calling callables
Besides building objects, the container can invoke a callable and autowire the arguments it does not receive explicitly. This is what a router or CLI framework uses to call a controller action or command handler: it passes the arguments it knows (route parameters, the request) and lets the container supply the rest from its bindings.
The call method
call accepts three shapes of callable:
- a
Closure, - an array
[object|class-string, method], - an invokable class string (a class with an
__invokemethod).
Each parameter of the callable is resolved the same way a constructor parameter is, using the autowiring rules from Autowiring and attributes.
<?php
declare(strict_types=1);
use Raxos\Container\Container;
$container = new Container();
$result = $container->call(static fn(Database $database): int =>
$database->count('users'));Overriding arguments
Named arguments passed in $args take precedence over autowired values. They are matched by parameter name, so any parameter present in the array is taken from it and the rest are autowired:
$container->call([$reportController, 'show'], [
'id' => 42,
]);Here id comes from the array, while a Database or Request parameter on show is resolved from the container.
Invokable classes
A class string that implements __invoke is instantiated (and autowired) before being called:
<?php
declare(strict_types=1);
final readonly class SendWelcomeMail
{
public function __construct(
public MailerInterface $mailer,
) {}
public function __invoke(User $user): void
{
$this->mailer->send(/* ... */);
}
}
$container->call(SendWelcomeMail::class, [
'user' => $user,
]);When the given value is not a closure, a valid [target, method] pair, or an invokable class string, call throws an InvalidCallableException.