示例#1
0
        public override async Task <object> Evaluate(EvaluationContext ctx)
        {
            var listCandidate = await ListCandidate.Evaluate(ctx);

            if (listCandidate == null)
            {
                // Template indexer implements null propagation out of the box
                return(null);
            }

            if (listCandidate is IList list)
            {
                if (Index < 0 || Index >= list.Count)
                {
                    // Template indexer implements null propagation out of the box
                    return(null);
                }

                return(list[Index]);
            }
            else
            {
                throw new TemplateException($"Indexer '#{Index}' is only valid on model entity lists.");
            }
        }
示例#2
0
        public override async Task GenerateOutput(StringBuilder builder, EvaluationContext ctx, Func <string, string> encodeFunc = null)
        {
            if (ListCandidate != null && Template != null)
            {
                var listObj = (await ListCandidate.Evaluate(ctx)) ?? new List <object>();
                if (listObj is IList list)
                {
                    int index = 0;
                    foreach (var listItem in list)
                    {
                        // Initialize new evaluation context with the new variable in it
                        var scopedCtx = ctx.Clone();
                        scopedCtx.SetLocalVariable(IteratorVariableName, new EvaluationVariable(
                                                       evalAsync: () => Task.FromResult(listItem),
                                                       selectResolver: () => AsyncUtil.Empty <Path>(), // It doesn't matter when generating output
                                                       pathsResolver: () => AsyncUtil.Empty <Path>()   // It doesn't matter when generating output
                                                       ));

                        // Index, useful for setting line numbers
                        scopedCtx.SetLocalVariable(IteratorVariableName + "_index", new EvaluationVariable(
                                                       evalAsync: () => Task.FromResult <object>(index),
                                                       selectResolver: () => AsyncUtil.Empty <Path>(), // It doesn't matter when generating output
                                                       pathsResolver: () => AsyncUtil.Empty <Path>()   // It doesn't matter when generating output
                                                       ));

                        // Run the template again on that context
                        await Template.GenerateOutput(builder, scopedCtx, encodeFunc);

                        index++;
                    }
                }
                else
                {
                    throw new TemplateException($"Foreach expression could not be applied. Expression ({ListCandidate}) does not evaluate to a list.");
                }
            }
        }