Callable Resolution
Overview
Callable resolution is a powerful feature of the DomainFlow Container that enables you to invoke arbitrary callables—such as closures, class methods, invokable objects, or named functions—with automatic dependency injection. When you call a function through the container, it inspects the callable’s parameters using PHP’s Reflection API and resolves any dependencies that are not explicitly provided.
Key Concepts
Automatic Dependency Injection:
The container examines a callable’s parameters and automatically injects any missing dependencies based on type hints.
Supported Callable Types:
The container supports a variety of callable forms:
Callable Type | Description |
---|---|
Closures | Directly supported, with automatic resolution of dependencies based on parameter type hints. |
Array Callables | Supports methods from a class (both static and instance methods), resolving their parameters automatically. |
Invokable Objects | Objects implementing an __invoke() method are treated as callables, with dependencies resolved similarly. |
String Callables | Functions specified as string names are also supported and have their parameters resolved. |
Error Handling:
If a parameter cannot be resolved (for instance, a built-in type without a default value), the container throws a meaningful exception to alert you during development.
Implementation Details
call()
This public method is the entry point for invoking callables. It accepts a callable along with an optional array of parameters. If some dependencies are missing from the provided parameters, they are automatically resolved using the container's dependency resolution mechanism.
Parameter | Type | Description |
---|---|---|
$callable | callable | The callable to be invoked. |
$parameters | array | Optional parameters; any missing dependencies will be resolved. |
doCall()
Internally, the container uses a method (often named doCall()
) that leverages PHP’s Reflection API to:
- Inspect the callable’s parameters.
- Resolve dependencies using the container’s resolution mechanism (commonly via the
make()
method). - Invoke the callable with a complete set of parameters.
This internal process supports all callable types, whether the callable is an object with an __invoke()
method, an array representing a class method, or a simple closure or function name.
Example Usage
Below is an example demonstrating how callable resolution works with different types of callables:
// Define a service class for demonstration.
class EmailService {
public function send($recipient, $message) {
echo "Email sent to {$recipient} with message: {$message}";
}
}
// Define a simple function that requires an instance of EmailService.
function notifyUser(EmailService $emailService, string $userEmail) {
$emailService->send($userEmail, "Welcome to our platform!");
}
// Create the container and bind EmailService.
$container = new Container();
$container->bind(EmailService::class, EmailService::class);
// Using callable resolution with a closure.
$container->call(function (EmailService $emailService) {
$emailService->send("[email protected]", "Hello from closure!");
});
// Using callable resolution with a simple function.
$container->call('notifyUser', [
'userEmail' => '[email protected]'
]);
// Using callable resolution with an array callable (class method).
class ReportGenerator {
public function generate(EmailService $emailService, string $reportName) {
$emailService->send("[email protected]", "Report: {$reportName}");
}
}
$container->bind(ReportGenerator::class, ReportGenerator::class);
$container->call([ReportGenerator::class, 'generate'], [
'reportName' => 'Monthly Sales'
]);
In this example:
- The container automatically injects an instance of
EmailService
into the callable even when not explicitly provided. - Different types of callables (anonymous functions, named functions, and array callables) are supported seamlessly.
Benefits of Callable Resolution
-
Simplified Code:
Eliminates the need for manual dependency injection when calling functions or methods, reducing boilerplate. -
Enhanced Flexibility:
Supports a wide variety of callable types, making it easy to integrate with your existing code. -
Robust Error Detection:
Automatically throws meaningful exceptions if dependencies cannot be resolved, aiding in debugging.
Summary
Callable resolution in the DomainFlow Container streamlines the process of invoking callables by automatically resolving and injecting dependencies. Leveraging PHP’s Reflection API, this feature enhances flexibility, reduces manual wiring, and improves error handling—making it an essential tool for building modular and maintainable applications.