Skip to content

SAIF.Framework.Windows business rules

This page captures business rules enforced by this library, covering entry-point orchestration, argument resolution, command-line parsing, dependency registration, logging, and data-access composition.

BR-WIN-001 Argument validation precedes application execution

Field Value
Statement Argument validation runs before any application dependency registration or resolution.
Trigger ProgramRunnerBase.Run() invoked.
Enforcement ProgramRunnerBase.Run()
Outcome RegisterAppDependencies/container build/app.Run() never execute if arguments are invalid.
Source Console\SAIF.Console\Console\ProgramRunnerBase.cs

BR-WIN-002 Unconfigured argument properties must be convertible or explicitly configured

Field Value
Statement Every settable property on an argument container not explicitly configured via BuildArgumentResolvers must be either auto-resolvable (IConvertible) or flagged as a validation error.
Trigger ArgumentContainerBase<T>.ResolveArguments() called.
Enforcement ArgumentContainerBase<T>.HandleUnconfiguredArguments
Outcome Non-convertible unconfigured properties produce a ValidationFailure; convertible ones are silently auto-bound.
Source Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.cs

BR-WIN-003 Invalid arguments halt before application logic

Field Value
Statement On invalid arguments, the process halts before running any application logic and requires a console keypress (Console.ReadLine()) before exiting.
Trigger Arguments.ResolveArguments().IsValid == false.
Enforcement ProgramRunnerBase.Run()
Outcome Environment.ExitCode = 1; errors written to Console.Error; method returns without further processing.
Source Console\SAIF.Console\Console\ProgramRunnerBase.cs

BR-WIN-004 SaifConsoleException supplies its own exit code

Field Value
Statement A thrown SaifConsoleException (or subclass) determines the process exit code from the exception's own ExitCode property, not a fixed value.
Trigger Exception of type SaifConsoleException escapes app.Run()/dependency resolution inside ProgramRunnerBase.Run()'s try.
Enforcement ProgramRunnerBase.Run() catch clause
Outcome Environment.ExitCode = ex.ExitCode; formatted exception text written to Console.Error.
Source Console\SAIF.Console\Console\ProgramRunnerBase.cs

BR-WIN-005 Unhandled exceptions default to exit code 5

Field Value
Statement Any unhandled, non-SaifConsoleException exception results in a fixed exit code of 5.
Trigger Any other Exception escapes the same try.
Enforcement ProgramRunnerBase.Run() catch clause
Outcome Environment.ExitCode = 5; formatted exception text written to Console.Error.
Source Console\SAIF.Console\Console\ProgramRunnerBase.cs

BR-WIN-006 Successful Initialize resets exit code

Field Value
Statement A successful Initialize() call always resets Environment.ExitCode to 0 before Execute() runs, regardless of any prior exit-code state.
Trigger ConsoleBase<TArgContainer>.Run() invoked.
Enforcement ConsoleBase<TArgContainer>.Run()
Outcome Environment.ExitCode = 0 set unconditionally between Initialize() and Execute().
Source Console\SAIF.Console\Console\ConsoleBase.cs

BR-WIN-007 Convertible properties auto-register

Field Value
Statement Argument-container properties whose type implements IConvertible are auto-registered for parsing/validation even without an explicit BuildArgumentResolvers setup call.
Trigger HandleUnconfiguredArguments runs during ResolveArguments().
Enforcement ArgumentContainerBase<T>.HandleUnconfiguredArguments
Outcome A resolver is dynamically constructed via reflection (BuilderSetupMethod.MakeGenericMethod) and added to the resolver set.
Source Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.cs

BR-WIN-008 Non-convertible unconfigured properties fail validation

Field Value
Statement Argument-container properties whose type does not implement IConvertible and are not explicitly configured are a validation failure, not a silent skip.
Trigger Same as BR-WIN-007, IConvertible check fails.
Enforcement ArgumentContainerBase<T>.HandleUnconfiguredArguments
Outcome ValidationFailure("{PropertyName} cannot be implicitly converted so it must be explicitly configured.") added.
Source Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.cs

BR-WIN-009 Missing required arguments fail validation

Field Value
Statement An argument configured as required (the ArgumentResolver default; not overridden via NotRequired()) that is absent from the parsed command line is a validation failure.
Trigger TryResolveArgument invoked for a required, unresolved argument.
Enforcement ArgumentResolver<TArgumentContainer, TArgument>.TryResolveArgument
Outcome ValidationFailure("{argumentName} is missing.") added; property left unset.
Source Console\SAIF.Console\Console\Arguments\ArgumentResolver.cs

BR-WIN-010 Argument value conversion failures fail validation

Field Value
Statement An argument value present on the command line that fails its configured propertyValueParser conversion is a validation failure, not a thrown exception up the stack.
Trigger AssignArgumentValue conversion throws.
Enforcement ArgumentResolver<TArgumentContainer, TArgument>.AssignArgumentValue
Outcome ValidationFailure("{name} '{value}' is not a valid {type}.") added; property left unset.
Source Console\SAIF.Console\Console\Arguments\ArgumentResolver.cs

BR-WIN-011 Flag-only arguments default to true

Field Value
Statement A two-token argument split (flag with no value, e.g. -verbose) is bound to the literal string "true".
Trigger PatternCommandLineParser.Parse splits a token into exactly 2 regex parts.
Enforcement PatternCommandLineParser.Parse
Outcome Dictionary entry {standardizedKey: "true"} added.
Source Console\SAIF.Console\Console\PatternCommandLineParser.cs

BR-WIN-012 First occurrence of duplicate argument keys wins

Field Value
Statement The first occurrence of a given standardized argument key wins; later duplicate keys in the same args array are ignored.
Trigger PatternCommandLineParser.Parse encounters a key already present in the result dictionary.
Enforcement PatternCommandLineParser.Parse
Outcome No dictionary update occurs for the duplicate occurrence.
Source Console\SAIF.Console\Console\PatternCommandLineParser.cs

BR-WIN-013 RegisterCommonDependencies requires non-null currentUserId

Field Value
Statement RegisterCommonDependencies requires a non-null currentUserId.
Trigger AutofacExtensions.RegisterCommonDependencies invoked.
Enforcement AutofacExtensions.RegisterCommonDependencies
Outcome Enforce.ArgumentNotNull throws if currentUserId is null.
Source Console\SAIF.Console\Console\AutofacExtensions.cs

BR-WIN-014 Log file environment variables map to fixed log types

Field Value
Statement Machine-level environment variable names are mapped to a fixed LogType set (file0–file4) by exact lower-cased name match; any non-matching name maps to LogType.Custom.
Trigger LogWriter constructed by ConsoleLogService.
Enforcement LogWriter constructor
Outcome LogType assigned from the knownLogTypes lookup dictionary, defaulting to Custom.
Source Console\SAIF.Console\Console\LogWriter.cs

BR-WIN-015 SQL Server has no stateless factory variant

Field Value
Statement SqlServerConfig's unit-of-work factory is always the single named "sqlSever" factory — SQL Server has no stateless-session variant in this framework (unlike Oracle).
Trigger SqlServerConfig.FactoryName evaluated during RegisterUnitOfWork.
Enforcement SqlServerConfig.FactoryName
Outcome The Stateless flag inherited from DatabaseConfig has no effect on which factory a SqlServerConfig resolves.
Source Console\SAIF.Console\Console\DatabaseConfigs\SqlServerConfig.cs

BR-WIN-016 Oracle factory selection driven by Stateless flag

Field Value
Statement OracleConfig's unit-of-work factory selection is driven by its own Stateless flag: true routes to "oracleStateless", otherwise "oracle".
Trigger OracleConfig.FactoryName evaluated during RegisterUnitOfWork.
Enforcement OracleConfig.FactoryName
Outcome Container resolves the named IUnitOfWorkFactory matching the computed factory name.
Source Console\SAIF.Console\Console\DatabaseConfigs\OracleConfig.cs

Notes

  • No ExitCode = 5 type is defined in this library; exit code 5 is reserved by BR-WIN-005's generic unhandled-exception catch clause in ProgramRunnerBase.Run().
  • ConsoleLogService's log-file discovery does not deduplicate machine environment variables pointing at the same file path; a commented-out duplicate-path check exists in source but is inactive and is not documented as active behavior.

Sources

  • Console\SAIF.Console\Console\ProgramRunnerBase.cs
  • Console\SAIF.Console\Console\ConsoleBase.cs
  • Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.cs
  • Console\SAIF.Console\Console\Arguments\ArgumentResolver.cs
  • Console\SAIF.Console\Console\PatternCommandLineParser.cs
  • Console\SAIF.Console\Console\AutofacExtensions.cs
  • Console\SAIF.Console\Console\LogWriter.cs
  • Console\SAIF.Console\Console\DatabaseConfigs\SqlServerConfig.cs
  • Console\SAIF.Console\Console\DatabaseConfigs\OracleConfig.cs