Argument resolution¶
ArgumentContainerBase<TArgumentContainer>.ResolveArguments() binds the raw command-line arguments (already parsed into a dictionary by command-line argument parsing) onto the argument container's properties, using explicit resolvers configured via BuildArgumentResolvers and reflection-driven auto-resolution for any remaining convertible property.
| Field | Value |
|---|---|
| Operation ID | OP-WIN-003 |
| Trigger | Called by program runner entry point step 2. |
| Inputs | The raw string[] args supplied to the constructor, already parsed into parsedArguments (Dictionary<string,string>) via the container's CommandLineParser. |
| Outputs | A ValidationResult (IsValid, Errors : IList<ValidationFailure>). |
| Primary components | ArgumentContainerBase<TArgumentContainer>.ResolveArguments(), HandleUnconfiguredArguments, ArgumentResolverBuilder<TArgumentContainer>, ArgumentResolver<TArgumentContainer, TArgument> |
| Entry point | Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.cs |
Steps¶
- Construct an
ArgumentResolverBuilder<TArgumentContainer>bound toCommandLineParser's parsed argument dictionary. - Call
BuildArgumentResolvers(builder)— a protected virtual, app-specific method (no-op by default) where the consuming argument container explicitly sets up resolvers viaHasPropertyConfiguration/Setup<TArgument>. HandleUnconfiguredArguments(builder)— for every settable property on the argument container not already configured by step 2:- If the property type implements
IConvertible: dynamically construct a resolver via reflection (BuilderSetupMethod.MakeGenericMethod) and add it to the resolver set (BR-WIN-007). - If the property type does not implement
IConvertible: addValidationFailure("{PropertyName} cannot be implicitly converted so it must be explicitly configured.")(BR-WIN-008). - This is enforced overall by BR-WIN-002: there is no silent-skip path for any settable property.
- For each resolver in
builder.GetResolvers(), callTryResolveArgument(container, parsedArguments, errors): - If the argument is required (the
ArgumentResolverdefault, not overridden viaNotRequired()) and absent from the parsed dictionary: addValidationFailure("{argumentName} is missing."); property left unset (BR-WIN-009). - If the argument is present but its configured
propertyValueParserconversion throws inAssignArgumentValue: addValidationFailure("{name} '{value}' is not a valid {type}."); property left unset (BR-WIN-010). - Otherwise: assign the converted value to the bound property.
- Return the accumulated
ValidationResult.
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([ResolveArguments called]) --> Build[BuildArgumentResolvers]
Build --> Unconfigured[HandleUnconfiguredArguments]
Unconfigured --> Convertible{Property IConvertible?}
Convertible -->|Yes| AutoResolver[Auto-register resolver]
Convertible -->|No| Fail1([ValidationFailure: must be explicitly configured])
AutoResolver --> TryResolve[TryResolveArgument per resolver]
TryResolve --> Present{Argument present?}
Present -->|No, required| Fail2([ValidationFailure: argument missing])
Present -->|Yes| Convert{Conversion succeeds?}
Convert -->|No| Fail3([ValidationFailure: not a valid type])
Convert -->|Yes| Assign([Property assigned])
Fail1 --> Result([Return ValidationResult])
Fail2 --> Result
Fail3 --> Result
Assign --> Result
Failure and edge-case behavior¶
- A property configured as
NotRequired()(orNotRequired(defaultValue)) that is absent from the command line does not produce a validation failure. - Multiple validation failures across different properties/resolvers all accumulate into the same
ValidationResult.Errorscollection rather than short-circuiting on the first failure.
Related documentation¶
Sources¶
Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.csConsole\SAIF.Console\Console\Arguments\ArgumentResolver.csConsole\SAIF.Console\Console\Arguments\ArgumentResolverBuilder.csConsole\SAIF.Console\Console\Arguments\IArgumentResolver.cs