Add some comments

This commit is contained in:
Alexey Golub
2019-08-18 15:03:53 +03:00
parent 08e2874eb4
commit 78ffaeb4b2
4 changed files with 15 additions and 6 deletions

View File

@@ -44,7 +44,7 @@ namespace CliFx.Internal
return type.GetInterfaces() return type.GetInterfaces()
.Select(GetEnumerableUnderlyingType) .Select(GetEnumerableUnderlyingType)
.ExceptNull() .ExceptNull()
.OrderByDescending(t => t != typeof(object)) .OrderByDescending(t => t != typeof(object)) // prioritize more specific types
.FirstOrDefault(); .FirstOrDefault();
} }

View File

@@ -35,19 +35,24 @@ namespace CliFx.Services
schema.GuardNotNull(nameof(schema)); schema.GuardNotNull(nameof(schema));
input.GuardNotNull(nameof(input)); input.GuardNotNull(nameof(input));
// Keep track of unset required options to report an error at a later stage
var unsetRequiredOptions = schema.Options.Where(o => o.IsRequired).ToList(); var unsetRequiredOptions = schema.Options.Where(o => o.IsRequired).ToList();
// Set command options // Set command options
foreach (var option in input.Options) foreach (var optionInput in input.Options)
{ {
var optionSchema = schema.Options.FindByAlias(option.Alias); // Find matching option schema for this option input
var optionSchema = schema.Options.FindByAlias(optionInput.Alias);
if (optionSchema == null) if (optionSchema == null)
continue; continue;
var convertedValue = _commandOptionInputConverter.ConvertOption(option, optionSchema.Property.PropertyType); // Convert option to the type of the underlying property
var convertedValue = _commandOptionInputConverter.ConvertOption(optionInput, optionSchema.Property.PropertyType);
// Set value of the underlying property
optionSchema.Property.SetValue(command, convertedValue); optionSchema.Property.SetValue(command, convertedValue);
// Mark this required option as set
if (optionSchema.IsRequired) if (optionSchema.IsRequired)
unsetRequiredOptions.Remove(optionSchema); unsetRequiredOptions.Remove(optionSchema);
} }

View File

@@ -150,7 +150,10 @@ namespace CliFx.Services
// Multiple values // Multiple values
else else
{ {
// Determine underlying type of elements inside the target collection type
var underlyingType = targetType.GetEnumerableUnderlyingType() ?? typeof(object); var underlyingType = targetType.GetEnumerableUnderlyingType() ?? typeof(object);
// Convert values to that type
var convertedValues = option.Values.Select(v => ConvertValue(v, underlyingType)).ToNonGenericArray(underlyingType); var convertedValues = option.Values.Select(v => ConvertValue(v, underlyingType)).ToNonGenericArray(underlyingType);
var convertedValuesType = convertedValues.GetType(); var convertedValuesType = convertedValues.GetType();
@@ -158,7 +161,7 @@ namespace CliFx.Services
if (targetType.IsAssignableFrom(convertedValuesType)) if (targetType.IsAssignableFrom(convertedValuesType))
return convertedValues; return convertedValues;
// Can be constructed from array of values (e.g. HashSet<T>, List<T>) // Has a constructor that accepts an array of values (e.g. HashSet<T>, List<T>)
var arrayConstructor = targetType.GetConstructor(new[] {convertedValuesType}); var arrayConstructor = targetType.GetConstructor(new[] {convertedValuesType});
if (arrayConstructor != null) if (arrayConstructor != null)
return arrayConstructor.Invoke(new object[] {convertedValues}); return arrayConstructor.Invoke(new object[] {convertedValues});

View File

@@ -31,6 +31,7 @@ namespace CliFx.Services
{ {
commandType.GuardNotNull(nameof(commandType)); commandType.GuardNotNull(nameof(commandType));
// Attribute is optional for commands in order to reduce runtime rule complexity
var attribute = commandType.GetCustomAttribute<CommandAttribute>(); var attribute = commandType.GetCustomAttribute<CommandAttribute>();
var options = commandType.GetProperties().Select(GetCommandOptionSchema).ExceptNull().ToArray(); var options = commandType.GetProperties().Select(GetCommandOptionSchema).ExceptNull().ToArray();