/// <summary> /// Updates this instance with a piece of data recieved from the completion of a user resolver function. /// This method performs no validation or resolution of the data, it simply assigns it as a value that was recieved /// from a resolver function and attaches it to this instance. /// </summary> /// <param name="data">The data.</param> public virtual void AssignResult(object data) { _childListItems = null; _childFields = null; this.ResultData = data; this.SetStatus(FieldItemResolutionStatus.ResultAssigned); // initialize the children of this instance from the assigned result if (this.IsListField) { if (this.ResultData == null) { return; } if (!GraphValidation.IsValidListType(this.ResultData.GetType())) { return; } if (!(this.ResultData is IEnumerable arraySource)) { return; } _childListItems = new List <GraphDataItem>(); // this instances's type expression is a list (or else we wouldnt be rendering out children) // strip out that outer most list component // to represent what each element of said list should be so that the rule // processor can validate the item as its own entity var childTypeExpression = this.TypeExpression.UnWrapExpression(MetaGraphTypes.IsList); var path = this.Path.Clone(); int index = 0; foreach (var item in arraySource) { var indexedPath = path.Clone(); indexedPath.AddArrayIndex(index++); var childItem = new GraphDataItem(this.FieldContext, item, indexedPath) { TypeExpression = childTypeExpression.Clone(), }; this.AddListItem(childItem); // child items are immediately resolved // using the enumerated source data from the resolver that supplied data // to this parent item. // that is to say that no child resolver is needed to be processed to // retrieve data for each child individually. childItem.AssignResult(item); childItem.SetStatus(this.Status); } } }
/// <summary> /// Adds a new field context item as a child of this field. Throws an exception /// if this data item contains list items. /// </summary> /// <param name="childListItem">The child list item.</param> public void AddListItem(GraphDataItem childListItem) { if (!this.IsListField) { throw new GraphExecutionException( $"The field {this.FieldContext.Field.Route.Path} represents " + "a collection of fields, a child list item cannot be directly added to it."); } _childListItems = _childListItems ?? new List <GraphDataItem>(); _childListItems.Add(childListItem); }
/// <summary> /// Copies the state of this instance into the provided instance. This is a direct replacement of the state of the /// target item. /// </summary> /// <param name="item">The item to copy the state to.</param> public void CopyTo(GraphDataItem item) { if (item == null) { return; } item.Status = this.Status; item.TypeExpression = this.TypeExpression; item.ResultData = this.ResultData; item._resultsDiscarded = this._resultsDiscarded; item._childFields = this._childFields == null ? null : new List <GraphDataItem>(this._childFields); item._childListItems = this._childListItems == null ? null : new List <GraphDataItem>(this._childListItems); }
/// <summary> /// Adds a new field context item as a child of this field. Throws an exception /// if this data item contains list items. /// </summary> /// <param name="childInvocationContext">The child invocation context.</param> /// <returns>GraphDataItem.</returns> public GraphDataItem AddChildField(IGraphFieldInvocationContext childInvocationContext) { if (this.IsListField) { throw new GraphExecutionException( $"The field {this.FieldContext.Field.Route.Path} represents " + "a list of items, a child field context cannot be directly added to it."); } _childFields = _childFields ?? new List <GraphDataItem>(); var path = this.Origin.Path.Clone(); path.AddFieldName(childInvocationContext.Field.Name); var childFieldItem = new GraphDataItem(childInvocationContext, this.ResultData, path); _childFields.Add(childFieldItem); return(childFieldItem); }