コード例 #1
0
        /// <summary>
        ///     Executes the specified formatter.
        /// </summary>
        /// <param name="formatter">The formatter.</param>
        /// <param name="sourceObject">The source object.</param>
        /// <param name="templateArguments">The template arguments.</param>
        /// <returns></returns>
        public virtual async Task <object> Execute(FormatTemplateElement formatter,
                                                   object sourceObject,
                                                   params KeyValuePair <string, object>[] templateArguments)
        {
            var values = ComposeValues(formatter, sourceObject, templateArguments);

            if (values == null)
            {
                Log(() => "Skip: Execute skip as Compose Values returned an invalid value");
                return(FormatterFlow.Skip);
            }

            if (formatter.CanFormat != null)
            {
                if (!formatter.CanFormat(sourceObject, templateArguments))
                {
                    Log(() => "Skip: Execute skip as CanExecute is false.");
                    return(FormatterFlow.Skip);
                }
            }

            Log(() => $"Execute");
            var taskAlike = formatter.Format.DynamicInvoke(values.Select(e => e.Value).ToArray());

            return(await taskAlike.UnpackFormatterTask());
        }
コード例 #2
0
 /// <summary>
 ///     Adds the formatter.
 /// </summary>
 /// <param name="formatter">The formatter.</param>
 public virtual FormatTemplateElement AddFormatter(FormatTemplateElement formatter)
 {
     if (ReplaceExisting)
     {
         Formatter.Remove(Formatter.FirstOrDefault(e => e.InputTypes == formatter.InputTypes));
     }
     Formatter.Add(formatter);
     return(formatter);
 }
コード例 #3
0
        /// <summary>
        ///     Executes the specified formatter.
        /// </summary>
        /// <param name="formatter">The formatter.</param>
        /// <param name="sourceObject">The source object.</param>
        /// <param name="templateArguments">The template arguments.</param>
        /// <returns></returns>
        public virtual object Execute([NotNull] FormatTemplateElement formatter,
                                      [CanBeNull] object sourceObject,
                                      params KeyValuePair <string, object>[] templateArguments)
        {
            var values = ComposeValues(formatter, sourceObject, templateArguments);

            if (values == null)
            {
                Write(() => "Skip: Execute skip as Compose Values returned an invalid value");
                return(FormatterFlow.Skip);
            }

            if (formatter.CanFormat != null)
            {
                if (!formatter.CanFormat(sourceObject, templateArguments))
                {
                    Write(() => "Skip: Execute skip as CanExecute is false.");
                    return(FormatterFlow.Skip);
                }
            }

            Write(() => $"Execute");
            return(formatter.Format.DynamicInvoke(values.Select(e => e.Value).ToArray()));
        }
コード例 #4
0
        /// <summary>
        ///     Composes the values into a Dictionary for each formatter. If returns null, the formatter will not be called.
        /// </summary>
        /// <param name="formatter">The formatter.</param>
        /// <param name="sourceObject">The source object.</param>
        /// <param name="templateArguments">The template arguments.</param>
        /// <returns></returns>
        public virtual IDictionary <MultiFormatterInfo, object> ComposeValues([NotNull] FormatTemplateElement formatter,
                                                                              [CanBeNull] object sourceObject, [NotNull] params KeyValuePair <string, object>[] templateArguments)
        {
            Write(() =>
                  $"Compose values for object '{sourceObject}' with formatter '{formatter.InputTypes}' targets '{formatter.Format.Method.Name}'");
            var values  = new Dictionary <MultiFormatterInfo, object>();
            var matched = new Dictionary <MultiFormatterInfo, KeyValuePair <string, object> >();

            foreach (var multiFormatterInfo in formatter.MetaData.Where(e => !e.IsRestObject))
            {
                Write(() => $"Match parameter '{multiFormatterInfo.Type}' [{multiFormatterInfo.Name}]");
                object givenValue;
                //set ether the source object or the value from the given arguments
                if (multiFormatterInfo.IsSourceObject)
                {
                    Write(() => "Is Source object");
                    givenValue = sourceObject;
                }
                else
                {
                    //match by index or name
                    Write(() => "Match by Name");
                    //match by name
                    var match = templateArguments.FirstOrDefault(e =>
                                                                 !string.IsNullOrWhiteSpace(e.Key) && e.Key.Equals(multiFormatterInfo.Name));

                    if (default(KeyValuePair <string, object>).Equals(match))
                    {
                        Write(() => "Match by Index");
                        //match by index
                        var index = 0;
                        match = templateArguments.FirstOrDefault(g => index++ == multiFormatterInfo.Index);
                    }

                    givenValue = match.Value;
                    Write(() => $"Matched '{match.Key}': '{match.Value}' by Name/Index");

                    //check for matching types
                    if (!multiFormatterInfo.Type.IsInstanceOfType(match.Value))
                    {
                        Write(() => "Skip: Match is Invalid because types from Template and Formatter mismatch. Abort.");
                        //The type in the template and the type defined in the formatter do not match. Abort
                        return(null);
                    }

                    matched.Add(multiFormatterInfo, match);
                }

                values.Add(multiFormatterInfo, givenValue);
                if (multiFormatterInfo.IsOptional || multiFormatterInfo.IsSourceObject)
                {
                    continue;                     //value and source object are optional so we do not to check for its existence
                }

                if (Equals(givenValue, null))
                {
                    Write(() =>
                          "Skip: Match is Invalid because template value is null where the Formatter does not have a optional value");
                    //the delegates parameter is not optional so this formatter does not fit. Continue.
                    return(null);
                }
            }

            var hasRest = formatter.MetaData.FirstOrDefault(e => e.IsRestObject);

            if (hasRest == null)
            {
                return(values);
            }

            Write(() => $"Match Rest argument '{hasRest.Type}'");

            //only use the values that are not matched.
            var restValues = templateArguments.Except(matched.Values);

            if (typeof(KeyValuePair <string, object>[]) == hasRest.Type)
            {
                //keep the name value pairs
                values.Add(hasRest, restValues);
            }
            else if (typeof(object[]).IsAssignableFrom(hasRest.Type))
            {
                //its requested to transform the rest values and truncate the names from it.
                values.Add(hasRest, restValues.Select(e => e.Value).ToArray());
            }
            else
            {
                Write(() => $"Skip: Match is Invalid because  '{hasRest.Type}' is no supported rest parameter");
                //unknown type in params argument cannot call
                return(null);
            }

            return(values);
        }
コード例 #5
0
 /// <summary>
 ///     Adds the formatter.
 /// </summary>
 /// <param name="formatter">The formatter.</param>
 public virtual FormatTemplateElement AddFormatter([NotNull] FormatTemplateElement formatter)
 {
     Formatter.Add(formatter);
     return(formatter);
 }
コード例 #6
0
        /// <inheritdoc />
        public async Task <object> Execute(FormatTemplateElement formatter, object sourceObject, params KeyValuePair <string, object>[] templateArguments)
        {
            await Task.CompletedTask;

            return(null);
        }
コード例 #7
0
 /// <inheritdoc />
 public FormatTemplateElement AddFormatter(FormatTemplateElement formatter)
 {
     return(ConstructEmptyMatcher());
 }