/// <summary> /// Executes a given constructor (identified by <paramref name="constructorSelector"/>) by reading values out of the picker /// (or prompting the user if <paramref name="pickerArgsIfAny"/> is null) /// </summary> /// <param name="toConstruct">The Type you want to construct</param> /// <param name="constructorSelector">Selects which constructor on <paramref name="toConstruct"/> you want to invoke</param> /// <param name="pickerArgsIfAny"></param> /// <returns></returns> protected object Construct(Type toConstruct, Func <ObjectConstructor, ConstructorInfo> constructorSelector, IEnumerable <CommandLineObjectPickerArgumentValue> pickerArgsIfAny = null) { var objectConstructor = new ObjectConstructor(); var invoker = new CommandInvoker(BasicActivator); var constructor = constructorSelector(objectConstructor); List <object> constructorValues = new List <object>(); var pickerEnumerator = pickerArgsIfAny?.GetEnumerator(); foreach (var parameterInfo in constructor.GetParameters()) { var required = new RequiredArgument(parameterInfo); var parameterDelegate = invoker.GetDelegate(required); if (parameterDelegate.IsAuto) { constructorValues.Add(parameterDelegate.Run(required)); } else { //it's not auto if (pickerEnumerator != null) { pickerEnumerator.MoveNext(); if (pickerEnumerator.Current == null) { throw new ArgumentException($"Value needed for parameter '{required.Name}' (of type '{required.Type}')"); } //construct with the picker arguments if (!pickerEnumerator.Current.HasValueOfType(required.Type)) { throw new NotSupportedException($"Argument '{pickerEnumerator.Current.RawValue}' could not be converted to required Type '{required.Type}' for argument {required.Name}"); } //it is a valid object yay! constructorValues.Add(pickerEnumerator.Current.GetValueForParameterOfType(required.Type)); } else { //construct by prompting user for the values constructorValues.Add(invoker.GetValueForParameterOfType(parameterInfo)); } } } pickerEnumerator?.Dispose(); return(constructor.Invoke(constructorValues.ToArray())); }
public CommandInvokerDelegate GetDelegate(RequiredArgument required) { var match = _argumentDelegates.FirstOrDefault(k => k.CanHandle(required.Type)); if (match != null) { return(match); } if (required.HasDefaultValue && required.DefaultValue != null) { return(new CommandInvokerFixedValueDelegate(required.DefaultValue)); } return(null); }
private object GetValueFor(RequiredArgument a) { return(GetDelegate(a)?.Run(a)); }
private T SelectOne <T>(RequiredArgument parameterInfo) { return((T)_basicActivator.SelectOne(parameterInfo.Name, _basicActivator.GetAll <T>().Cast <IMapsDirectlyToDatabaseTable>().ToArray())); }
private void ExecuteCommand(ConstructorInfo constructorInfo, CommandLineObjectPicker picker) { List <object> parameterValues = new List <object>(); bool complainAboutExtraParameters = true; int idx = 0; //for each parameter on the constructor we want to invoke foreach (var parameterInfo in constructorInfo.GetParameters()) { var required = new RequiredArgument(parameterInfo); var argDelegate = GetDelegate(required); //if it is an easy one to automatically fill e.g. IBasicActivateItems if (argDelegate != null && argDelegate.IsAuto) { parameterValues.Add(argDelegate.Run(required)); } else //if the constructor argument is a picker, use the one passed in if (parameterInfo.ParameterType == typeof(CommandLineObjectPicker)) { if (picker == null) { throw new ArgumentException($"Type {constructorInfo.DeclaringType} contained a constructor which took an {parameterInfo.ParameterType} but no picker was passed"); } parameterValues.Add(picker); //the parameters are expected to be consumed by the target constructors so it's not really a problem if there are extra complainAboutExtraParameters = false; continue; } else //if we have argument values specified if (picker != null) { //and the specified value matches the expected parameter type if (picker.HasArgumentOfType(idx, parameterInfo.ParameterType)) { //consume a value parameterValues.Add(picker[idx].GetValueForParameterOfType(parameterInfo.ParameterType)); idx++; continue; } throw new Exception($"Expected parameter at index {idx} to be a {parameterInfo.ParameterType} (for parameter '{parameterInfo.Name}') but it was {(idx >= picker.Length ? "Missing":picker[idx].RawValue)}"); } else { parameterValues.Add(GetValueForParameterOfType(parameterInfo)); } } if (picker != null && idx < picker.Length && complainAboutExtraParameters) { throw new Exception("Unrecognised extra parameter " + picker[idx].RawValue); } var instance = (IAtomicCommand)constructorInfo.Invoke(parameterValues.ToArray()); if (instance.IsImpossible) { CommandImpossible?.Invoke(this, new CommandEventArgs(instance)); return; } instance.Execute(); CommandCompleted?.Invoke(this, new CommandEventArgs(instance)); }
private T[] SelectMany <T>(RequiredArgument parameterInfo) { return (_basicActivator.SelectMany(parameterInfo.Name, typeof(T), _basicActivator.GetAll <T>().Cast <IMapsDirectlyToDatabaseTable>().ToArray()) .Cast <T>().ToArray()); }
public object GetValueForParameterOfType(RequiredArgument a) { return(GetDelegate(a)?.Run(a)); }
private string GetPromptFor(RequiredArgument p) { return($"Value needed for {p.Name} ({p.Type.Name})"); }
private IPipeline SelectPipeline(RequiredArgument arg) { return((IPipeline)_basicActivator.SelectOne(GetPromptFor(arg), _basicActivator.RepositoryLocator.CatalogueRepository.GetAllObjects <Pipeline>().ToArray())); }