Skip to content

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

  1. Construct an ArgumentResolverBuilder<TArgumentContainer> bound to CommandLineParser's parsed argument dictionary.
  2. Call BuildArgumentResolvers(builder) — a protected virtual, app-specific method (no-op by default) where the consuming argument container explicitly sets up resolvers via HasPropertyConfiguration/Setup<TArgument>.
  3. HandleUnconfiguredArguments(builder) — for every settable property on the argument container not already configured by step 2:
  4. If the property type implements IConvertible: dynamically construct a resolver via reflection (BuilderSetupMethod.MakeGenericMethod) and add it to the resolver set (BR-WIN-007).
  5. If the property type does not implement IConvertible: add ValidationFailure("{PropertyName} cannot be implicitly converted so it must be explicitly configured.") (BR-WIN-008).
  6. This is enforced overall by BR-WIN-002: there is no silent-skip path for any settable property.
  7. For each resolver in builder.GetResolvers(), call TryResolveArgument(container, parsedArguments, errors):
  8. If the argument is required (the ArgumentResolver default, not overridden via NotRequired()) and absent from the parsed dictionary: add ValidationFailure("{argumentName} is missing."); property left unset (BR-WIN-009).
  9. If the argument is present but its configured propertyValueParser conversion throws in AssignArgumentValue: add ValidationFailure("{name} '{value}' is not a valid {type}."); property left unset (BR-WIN-010).
  10. Otherwise: assign the converted value to the bound property.
  11. 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() (or NotRequired(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.Errors collection rather than short-circuiting on the first failure.

Sources

  • Console\SAIF.Console\Console\Arguments\ArgumentContainerBase.cs
  • Console\SAIF.Console\Console\Arguments\ArgumentResolver.cs
  • Console\SAIF.Console\Console\Arguments\ArgumentResolverBuilder.cs
  • Console\SAIF.Console\Console\Arguments\IArgumentResolver.cs