Problem Statement
CommandDiscovery::instantiateCommands() hardcodes new $className(), which means auto-discovered commands must have zero-argument constructors. Commands that require dependencies (DB connections, services, config) cannot use auto-discovery — they must be registered manually.
Proposed Solution
Add a factory callable to CommandDiscovery:
private $factory = null;
public function setFactory(callable $factory): self {
$this->factory = $factory;
return $this;
}
Modify instantiateCommands():
$commands[] = $this->factory
? ($this->factory)($className)
: new $className();
Usage with a container:
$runner->getCommandDiscovery()->setFactory(fn($class) => $container->get($class));
$runner->addDiscoveryPath('src/Commands');
Usage without a container (unchanged):
$runner->addDiscoveryPath('src/Commands'); // works as before
Alternatives Considered
- Integrate PSR-11 ContainerInterface — rejected. Adds a dependency, not the CLI library's responsibility.
- Leave as-is — rejected. Forces users with DI to abandon auto-discovery entirely.
Breaking Change
No. Default behavior (no factory set) remains new $className().
Additional Context
~5 lines of implementation. Enables webfiori/container or any PSR-11 container to work with auto-discovery without the CLI library depending on either.
Problem Statement
CommandDiscovery::instantiateCommands()hardcodesnew $className(), which means auto-discovered commands must have zero-argument constructors. Commands that require dependencies (DB connections, services, config) cannot use auto-discovery — they must be registered manually.Proposed Solution
Add a factory callable to
CommandDiscovery:Modify
instantiateCommands():Usage with a container:
Usage without a container (unchanged):
Alternatives Considered
Breaking Change
No. Default behavior (no factory set) remains
new $className().Additional Context
~5 lines of implementation. Enables
webfiori/containeror any PSR-11 container to work with auto-discovery without the CLI library depending on either.