A lightweight, powerful Dependency Injection (DI) Container designed for the WpMVC framework. It provides automatic dependency resolution, singleton management, and flexible method invocation capabilities.
composer require wpmvc/container- Zero Configuration: Automatically resolves dependencies using PHP Reflection.
- Singleton Pattern: Maintains single instances of services via
get(). - Factory Pattern: Creates fresh instances on demand via
make(). - Method Injection: Supports dependency injection for method calls via
call(). - Circular Dependency Detection: Prevents infinite loops during resolution errors.
- Parameter Overrides: Allows passing specific parameters to constructors and methods.
- PSR-4 Compatible: designed for modern PHP applications.
use WpMVC\Container;
$container = new Container();The get method retrieves a service. If the service has not been created yet, the container will attempt to instantiate it, resolving any dependencies automatically. Subsequent calls return the same instance.
$service = $container->get(MyService::class);The make method always creates a new instance of the requested class, resolving dependencies afresh.
$freshInstance = $container->make(MyService::class);You can manually register an existing instance into the container.
$container->set(MyInterface::class, new MyConcreteImplementation());Check if a service is available (either instantiated or the class exists).
if ($container->has(MyService::class)) {
// ...
}The container uses PHP's Reflection API to inspect class constructors.
If your class looks like this:
class Database { ... }
class UserRepository {
protected $db;
public function __construct(Database $db) {
$this->db = $db;
}
}Calling $container->get(UserRepository::class) will automatically:
- Detect
Databasedependency. - Resolve
Databasevia$container->get(Database::class). - Instantiate
UserRepositorywith the resolvedDatabaseinstance.
You can pass an array of parameters to get() or make() to override dependencies or provide primitive values (strings, ints, etc.). Keys must match the constructor parameter names.
class ApiClient {
public function __construct(HttpClient $client, string $apiKey) { ... }
}
$client = $container->get(ApiClient::class, [
'apiKey' => 'secret_123', // Matches $apiKey
// 'client' => $mockClient // Optional: could also override the object dependency
]);The call method allows you to execute any callable (function, closure, object method) while automatically injecting its dependencies.
class ReportController {
public function generate(ReportService $service, $format = 'json') {
return $service->build($format);
}
}
// Automatically resolves ReportService and injects it.
// $format uses the default value 'json' unless overridden in params.
$result = $container->call([ReportController::class, 'generate'], [
'format' => 'pdf'
]);Supported callback formats:
'ClassName::method'(Static calls, or auto-resolves instance for non-static)[$object, 'method'][ClassName::class, 'method']- Closures / Anonymous functions
The container tracks currently resolving classes. If Class A depends on Class B, and Class B depends on Class A, the container will throw an Exception to prevent an infinite loop / stack overflow.
Exception: Circular dependency detected while resolving: WpMVC\ClassA
- PHP 7.4 or higher