Program runner entry point¶
ProgramRunnerBase<TApplication, TArgumentContainer>.Run() (and its override in SaifStandardProgramBase<TApp, TArgContainer>) is the top-level orchestrator a consuming console application calls from Main(). It resolves and validates command-line arguments, composes the Autofac container, resolves the concrete application, runs it, and maps any escaping exception to a process exit code.
| Field | Value |
|---|---|
| Operation ID | OP-WIN-001 |
| Trigger | Consuming application's Main() constructs a ProgramRunnerBase/SaifStandardProgramBase subclass and calls Run(). |
| Inputs | RawArguments (abstract property; SaifStandardProgramBase supplies Environment.GetCommandLineArgs()). |
| Outputs | Process Environment.ExitCode; console/stderr output. |
| Primary components | ProgramRunnerBase<TApplication, TArgumentContainer>.Run(), SaifStandardProgramBase<TApp, TArgContainer>.Run() |
| Entry point | Console\SAIF.Console\Console\ProgramRunnerBase.cs |
Steps¶
Arguments = CreateArgumentContainer(RawArguments)— delegates to the abstract, app-specific factory method.var result = Arguments.ResolveArguments()— delegates into argument resolution, enforcing BR-WIN-001 and BR-WIN-002.- Embedded sub-steps from argument resolution: construct an
ArgumentResolverBuilder<TArgumentContainer>, callBuildArgumentResolvers(app-specific, no-op by default), auto-register any unconfiguredIConvertibleproperty (BR-WIN-007) or flag it as a validation failure (BR-WIN-008), then run each resolver'sTryResolveArgumentagainst the parsed argument dictionary. - Branch — if
!result.IsValid: writes allValidationFailuremessages toConsole.Error(viaDisplayErrors), setsEnvironment.ExitCode = 1, callsSystem.Console.ReadLine()(blocks for a keypress before returning), and returns without registering dependencies, building the container, or running the application (BR-WIN-003). RegisterAppDependencies(builder)— delegates to the abstract, app-specific Autofac composition root, then registersCreateApplicationas a component factory on the samebuilder.- The consuming application's
RegisterAppDependenciesoverride is expected to call dependency and unit-of-work registration. using (var container = builder.Build())— builds the Autofac container for the scope of this run.var app = container.Resolve<TApplication>()— resolves the concrete application instance (invokes itsConsoleBaseconstructor, which setsStartTimeand callsWriteHeader()).- Resolves
IUserProfileService.GetCurrentUser().UserIdandIEnvironmentService.GetApplicationTrack()and writes"Running as: {userId} on track: {track}"to the console (WriteCurrentUserAndTrack). app.Run()— delegates into the console application lifecycle.- Exception handling around steps 6–8:
- On a caught
SaifConsoleException: writesex.GetFullFormattedException()toConsole.Errorand setsEnvironment.ExitCode = ex.ExitCode(BR-WIN-004). - On any other caught
Exception: writes the same formatted output and setsEnvironment.ExitCode = 5(BR-WIN-005). SaifStandardProgramBase.Run()(override) callsbase.Run()then always prints"Exit Code: " + Environment.ExitCodeto the console, regardless of outcome.
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([Main calls Run]) --> CreateArgs[CreateArgumentContainer]
CreateArgs --> Resolve[Arguments.ResolveArguments]
Resolve --> Valid{IsValid?}
Valid -->|No| Halt([ExitCode=1, Console.Error, ReadLine block])
Valid -->|Yes| Register[RegisterAppDependencies + Build container]
Register --> ResolveApp[Resolve TApplication]
ResolveApp --> Banner[Write current user and track]
Banner --> AppRun[app.Run]
AppRun --> Outcome{Exception?}
Outcome -->|SaifConsoleException| ExitEx([ExitCode = ex.ExitCode])
Outcome -->|Other| Exit5([ExitCode = 5])
Outcome -->|No| Exit0([ExitCode unchanged / 0])
Failure and edge-case behavior¶
- Invalid arguments prevent any dependency registration, container build, or application resolution; the process blocks on a console keypress before returning (BR-WIN-003).
- A
SaifConsoleExceptionsubclass's ownExitCodeis always honored over the generic fallback of5. SaifStandardProgramBase.Run()always prints the final exit code, even on the success path.
Related documentation¶
Sources¶
Console\SAIF.Console\Console\ProgramRunnerBase.csConsole\SAIF.Console\Console\SaifStandardProgramBase.cs