public static CommandValueLookup GetParameterValues(CommandTree?tree, ITypeResolver resolver) { var lookup = new CommandValueLookup(); var binder = new CommandValueBinder(lookup); CommandValidator.ValidateRequiredParameters(tree); while (tree != null) { // Process unmapped parameters. foreach (var parameter in tree.Unmapped) { if (parameter.IsFlagValue()) { // Set the flag value to an empty, not set instance. var instance = Activator.CreateInstance(parameter.ParameterType); lookup.SetValue(parameter, instance); } else { // Is this an option with a default value? if (parameter is CommandOption option && option.DefaultValue != null) { binder.Bind(parameter, resolver, option.DefaultValue?.Value); CommandValidator.ValidateParameter(parameter, lookup); } } } // Process mapped parameters. foreach (var mapped in tree.Mapped) { if (mapped.Parameter.WantRawValue) { // Just try to assign the raw value. binder.Bind(mapped.Parameter, resolver, mapped.Value); } else { var converter = GetConverter(lookup, binder, resolver, mapped.Parameter); if (converter == null) { throw RuntimeException.NoConverterFound(mapped.Parameter); } if (mapped.Parameter.IsFlagValue() && mapped.Value == null) { if (mapped.Parameter is CommandOption option && option.DefaultValue != null) { // Set the default value. binder.Bind(mapped.Parameter, resolver, option.DefaultValue?.Value); } else { // Set the flag but not the value. binder.Bind(mapped.Parameter, resolver, null); } }
public static CommandSettings CreateSettings(CommandValueLookup lookup, ConstructorInfo constructor, ITypeResolver resolver) { if (constructor.DeclaringType == null) { throw new InvalidOperationException("Cannot create settings since constructor have no declaring type."); } var parameters = new List <object?>(); var mapped = new HashSet <Guid>(); foreach (var parameter in constructor.GetParameters()) { if (lookup.TryGetParameterWithName(parameter.Name, out var result)) { parameters.Add(result.Value); mapped.Add(result.Parameter.Id); } else { var value = resolver.Resolve(parameter.ParameterType); if (value == null) { throw CommandRuntimeException.CouldNotResolveType(parameter.ParameterType); } parameters.Add(value); } } // Create the settings. if (!(Activator.CreateInstance(constructor.DeclaringType, parameters.ToArray()) is CommandSettings settings)) { throw new InvalidOperationException("Could not create settings"); } // Try to do property injection for parameters that wasn't injected. foreach (var(parameter, value) in lookup) { if (!mapped.Contains(parameter.Id) && parameter.Property.SetMethod != null) { parameter.Property.SetValue(settings, value); } } return(settings); }
public static CommandSettings CreateSettings(CommandValueLookup lookup, Type settingsType, ITypeResolver resolver) { var settings = CreateSettings(resolver, settingsType); foreach (var (parameter, value) in lookup) { parameter.Property.SetValue(settings, value); } // Validate the settings. var validationResult = settings.Validate(); if (!validationResult.Successful) { throw CommandRuntimeException.ValidationFailed(validationResult); } return settings; }
public static void ValidateParameter(CommandParameter parameter, CommandValueLookup settings) { var assignedValue = settings.GetValue(parameter); foreach (var validator in parameter.Validators) { var validationResult = validator.Validate(parameter, assignedValue); if (!validationResult.Successful) { // If there is a error message specified in the parameter validator attribute, // then use that one, otherwise use the validation result. var result = string.IsNullOrWhiteSpace(validator.ErrorMessage) ? validationResult : ValidationResult.Error(validator.ErrorMessage); throw CommandRuntimeException.ValidationFailed(result); } } }
public CommandValueBinder(CommandValueLookup lookup) { _lookup = lookup; }
public static CommandValueLookup GetParameterValues(CommandTree?tree, ITypeResolver resolver) { var lookup = new CommandValueLookup(); var binder = new CommandValueBinder(lookup); CommandValidator.ValidateRequiredParameters(tree); while (tree != null) { // Process unmapped parameters. foreach (var parameter in tree.Unmapped) { // Got a value provider? if (parameter.ValueProvider != null) { var context = new CommandParameterContext(parameter, resolver, null); if (parameter.ValueProvider.TryGetValue(context, out var result)) { result = ConvertValue(resolver, lookup, binder, parameter, result); lookup.SetValue(parameter, result); CommandValidator.ValidateParameter(parameter, lookup, resolver); continue; } } if (parameter.IsFlagValue()) { // Set the flag value to an empty, not set instance. var instance = Activator.CreateInstance(parameter.ParameterType); lookup.SetValue(parameter, instance); } else { // Is this an option with a default value? if (parameter.DefaultValue != null) { var value = parameter.DefaultValue?.Value; value = ConvertValue(resolver, lookup, binder, parameter, value); binder.Bind(parameter, resolver, value); CommandValidator.ValidateParameter(parameter, lookup, resolver); } else if (Nullable.GetUnderlyingType(parameter.ParameterType) != null || !parameter.ParameterType.IsValueType) { lookup.SetValue(parameter, null); } } } // Process mapped parameters. foreach (var mapped in tree.Mapped) { if (mapped.Parameter.WantRawValue) { // Just try to assign the raw value. binder.Bind(mapped.Parameter, resolver, mapped.Value); } else { if (mapped.Parameter.IsFlagValue() && mapped.Value == null) { if (mapped.Parameter is CommandOption option && option.DefaultValue != null) { // Set the default value. binder.Bind(mapped.Parameter, resolver, option.DefaultValue?.Value); } else { // Set the flag but not the value. binder.Bind(mapped.Parameter, resolver, null); } }