Skip to content

#Refactor CLI command dispatch: replace reflection-based partial Program god-class with IFalloutCommand types #392

Description

@ChrisonSimtian

Problem

Fallout.Cli implements every CLI command as a static int method on one partial class Program, split across ~10 Program.*.cs files and dispatched by reflection (Program.Handle reflects over its own int-returning methods). The partial split looks organized, but the underlying type is a god object — it owns dispatch, secrets, packages, Cake interop, navigation, config, run orchestration, and the Spectre prompts. Reflection dispatch is stringly-typed: a typo'd signature compiles and fails at runtime, and nothing is DI-able or unit-testable in isolation.

Outcome

One command = one type behind a typed IFalloutCommand, discovered by type via DI instead of reflection. The :command CLI surface and shell-function names stay exactly as they are (non-breaking).

public interface IFalloutCommand
{
    string Name { get; }   // e.g. "run", "setup"
    int Execute(string[] args, AbsolutePath rootDirectory, AbsolutePath buildScript);
}

Each Program.X.cs partial becomes a standalone XCommand implementing IFalloutCommand; the dispatcher resolves by Name. The partial keyword disappears. Shared helpers move into injectable services in the final collapse PR.

Acceptance criteria

  • IFalloutCommand + a type/DI-based dispatcher replace reflection dispatch
  • Every command is its own type; Program collapses to a thin entry point (no partial)
  • CLI command names + shell-function spellings unchanged (dash/case-insensitive preserved)
  • Dispatch has unit-test coverage
  • Shared helpers extracted into injectable services

Approach

Incremental — one command per PR behind a transitional DelegateCommand adapter so nothing regresses. Tracked by the #394 stack.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions