///<summary> /// Uses the action pipeline to invoke the method. ///</summary> ///<param name="target"> The object instance to invoke the method on. </param> ///<param name="methodName"> The name of the method to invoke. </param> ///<param name="view"> The view. </param> ///<param name="source"> The source of the invocation. </param> ///<param name="eventArgs"> The event args. </param> ///<param name="parameters"> The method parameters. </param> public static void Invoke(object target, string methodName, DependencyObject view = null, FrameworkElement source = null, object eventArgs = null, object[] parameters = null) { var message = new ActionMessage { MethodName = methodName }; var context = new ActionExecutionContext { Target = target, #if WINDOWS_UWP Method = target.GetType().GetRuntimeMethods().Single(m => m.Name == methodName), #else Method = target.GetType().GetMethod(methodName), #endif Message = message, View = view, Source = source, EventArgs = eventArgs }; if (parameters != null) { parameters.Apply(x => context.Message.Parameters.Add(x as Parameter ?? new Parameter { Value = x })); } ActionMessage.InvokeAction(context); // This is a bit of hack but keeps message being garbage collected Log.Info("Invoking action {0} on {1}.", message.MethodName, target); }
/// <summary> /// Try to find a candidate for guard function, having: /// - a name matching any of <paramref name="possibleGuardNames"/> /// - no generic parameters /// - a bool return type /// - no parameters or a set of parameters corresponding to the action method /// </summary> /// <param name="context">The execution context</param> /// <param name="possibleGuardNames">Method names to look for.</param> ///<returns>A MethodInfo, if found; null otherwise</returns> static MethodInfo TryFindGuardMethod(ActionExecutionContext context, IEnumerable <string> possibleGuardNames) { var targetType = context.Target.GetType(); MethodInfo guard = null; foreach (string possibleGuardName in possibleGuardNames) { guard = GetMethodInfo(targetType, possibleGuardName); if (guard != null) { break; } } if (guard == null) { return(null); } if (guard.ContainsGenericParameters) { return(null); } if (!typeof(bool).Equals(guard.ReturnType)) { return(null); } var guardPars = guard.GetParameters(); var actionPars = context.Method.GetParameters(); if (guardPars.Length == 0) { return(guard); } if (guardPars.Length != actionPars.Length) { return(null); } var comparisons = guardPars.Zip( context.Method.GetParameters(), (x, y) => x.ParameterType == y.ParameterType ); if (comparisons.Any(x => !x)) { return(null); } return(guard); }
void UpdateContext() { if (context != null) { context.Dispose(); } context = new ActionExecutionContext { Message = this, Source = AssociatedObject }; PrepareContext(context); UpdateAvailabilityCore(); }
/// <summary> /// Determines the parameters that a method should be invoked with. /// </summary> /// <param name="context">The action execution context.</param> /// <param name="requiredParameters">The parameters required to complete the invocation.</param> /// <returns>The actual parameter values.</returns> public static object[] DetermineParameters(ActionExecutionContext context, ParameterInfo[] requiredParameters) { var providedValues = context.Message.Parameters.OfType <Parameter>().Select(x => x.Value).ToArray(); var finalValues = new object[requiredParameters.Length]; for (int i = 0; i < requiredParameters.Length; i++) { var parameterType = requiredParameters[i].ParameterType; var parameterValue = providedValues[i]; var parameterAsString = parameterValue as string; if (parameterAsString != null) { finalValues[i] = CoerceValue(parameterType, EvaluateParameter(parameterAsString, parameterType, context), context); } else { finalValues[i] = CoerceValue(parameterType, parameterValue, context); } } return(finalValues); }