Skip to content

feat(discovery): Add command factory callable for auto-discovery #48

@usernane

Description

@usernane

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions