Console application execution lifecycle¶
This is the template-method lifecycle every console or batch application built on this library follows. clsConsoleBase.Execute() fixes the order of initialization, command-line validation, main-logic execution, and teardown; a batch subclass (clsBatchBase) does not override Execute() itself but overrides Initialize()/Uninitialize() to add multi-stream log registration and a batch header/footer around the same lifecycle.
| Field | Value |
|---|---|
| Operation ID | OP-CA-001 |
| Trigger | Downstream Sub Main instantiates a clsConsoleBase/clsBatchBase subclass and calls Execute() |
| Inputs | Command-line arguments (Environment.GetCommandLineArgs); for a batch subclass, also the set of currently defined environment variables |
| Outputs | ReturnCode / Environment.ExitCode; console output (batch header/footer, prompts); for a batch subclass, flushed/closed log-stream files |
| Primary components | clsConsoleBase.Execute, clsConsoleBase.Initialize, clsConsoleBase.Uninitialize, clsBatchBase.Initialize, clsBatchBase.Uninitialize, clsBatchBase.WriteBatchHeader, clsBatchBase.WriteBatchFooter |
| Entry point | Presentation\SAIF.Presentation.ConsoleApplication\clsConsoleBase.vb |
Steps¶
- Construct the application object. The subclass's constructor runs
clsConsoleBase.New(), which recordsm_StartTime = Nowfor later use byRunningTime/WriteBatchFooter. - Initialize.
Execute()callsInitialize(). - Base behavior (
clsConsoleBase.Initialize): setsReturnCode = ReturnCodes.UnknownErroras the default exit code, then readsEnvironment.GetCommandLineArgs, and for each argument strips a single leading/or-and upper-cases it before storing it (BR-002). - If the subclass is a
clsBatchBase:Initialize()is overridden — it callsMyBase.Initialize()first (running the base behavior above), then scans every current environment variable name and pre-registers any whose upper-cased name matches the patternFILE?(e.g.,FILE0…FILE4) into an internal log-stream table with an empty placeholder value, then callsWriteBatchHeader(), which writes"<AppName> began at <StartTime>"to the console viaWriteStatusMsg. - Check for a debug flag.
Execute()callsParamExists("DEBUG")(BR-005); the result is not currently wired to any observable behavior in this library.* - Validate the command line.
Execute()calls the abstractValidateCommandLine(), implemented by the concrete downstream application. - Branch on validation result (BR-003):
- If
True:Execute()calls the abstractRunAppLogic(), the concrete application's main logic. - If
False:Execute()writes"Press enter to continue..."to the console and blocks onConsole.Read()instead of callingRunAppLogic(). - Uninitialize.
Execute()always callsUninitialize()after the branch above, regardless of which path was taken. - If the subclass is a
clsBatchBase:Uninitialize()is overridden — it callsWriteBatchFooter()first, which writes"<AppName> ended at <EndTime>"and"<AppName> ran for <seconds> seconds"to the console; then, for every log-stream entry that was actually opened as aStreamWriter(not left as its empty placeholder string), it flushes and closes that stream; only then does it callMyBase.Uninitialize()(the base implementation is a no-op). - Return.
Execute()returns; the process'sEnvironment.ExitCodereflects whatever value was last assigned toReturnCode(defaulting toUnknownErrorfrom step 2 unlessRunAppLogic()or another step explicitly sets a different value).*
Process flow¶
The following diagram visualizes the Execute() template-method lifecycle, including the batch-specific extensions to Initialize()/Uninitialize().
flowchart TD
Start([Sub Main calls Execute]) --> Init[Initialize:<br>default ReturnCode,<br>parse command line]
Init --> IsBatch{Batch subclass?}
IsBatch -->|Yes| BatchInit[Pre-register FILE?<br>environment variables;<br>write batch header]
IsBatch -->|No| Debug
BatchInit --> Debug{DEBUG flag present?}
Debug --> Validate{ValidateCommandLine}
Validate -->|True| Run[RunAppLogic]
Validate -->|False| Prompt["Press enter to continue..."]
Run --> Uninit[Uninitialize]
Prompt --> Uninit
Uninit --> IsBatch2{Batch subclass?}
IsBatch2 -->|Yes| BatchUninit[Write batch footer;<br>flush/close opened log streams]
IsBatch2 -->|No| End
BatchUninit --> End([Return; ExitCode reflects ReturnCode])
Failure and edge-case behavior¶
- When
ValidateCommandLine()returnsFalse,RunAppLogic()is never invoked; the process instead waits indefinitely onConsole.Read()for operator input before proceeding toUninitialize()(BR-003). Uninitialize()always runs after the validate/run branch, so batch log streams are flushed and closed even whenRunAppLogic()was never called.ReturnCodedefaults toUnknownErrorat the start ofInitialize(); if the concreteRunAppLogic()implementation completes without explicitly settingReturnCode, the process exits withUnknownErrorrather thanSuccess.*- The
/DEBUGcheck inExecute()callsParamExists("DEBUG")but the result is not used to alter logging or control flow anywhere in this library's source.* clsBatchBase.Uninitializeonly flushes/closes log-stream entries whose stored value is not still the placeholder empty string — a stream that was pre-registered but never actually written to viaWriteAppLogMsgis left unopened and is skipped.
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Related documentation¶
Sources¶
Presentation\SAIF.Presentation.ConsoleApplication\clsConsoleBase.vbPresentation\SAIF.Presentation.ConsoleApplication\clsBatchBase.vb