Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BatchResultProcessor" /> class.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <param name="sourceItems">The source items.</param>
 /// <param name="origin">The origin.</param>
 public BatchResultProcessor(IGraphField field, IEnumerable <GraphDataItem> sourceItems, SourceOrigin origin)
 {
     _origin       = origin;
     _field        = Validation.ThrowIfNullOrReturn(field, nameof(field));
     _sourceItems  = Validation.ThrowIfNullOrReturn(sourceItems, nameof(sourceItems));
     this.Messages = new GraphMessageCollection();
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="IntrospectedInputValueType"/> class.
        /// </summary>
        /// <param name="inputField">The field of an input object used to populate this value.</param>
        /// <param name="introspectedGraphType">The meta data representing the type of this argument.</param>
        public IntrospectedInputValueType(IGraphField inputField, IntrospectedType introspectedGraphType)
        {
            Validation.ThrowIfNull(inputField, nameof(inputField));
            this.IntrospectedGraphType = Validation.ThrowIfNullOrReturn(introspectedGraphType, nameof(introspectedGraphType));

            this.Name        = inputField.Name;
            this.Description = inputField.Description;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldContextBuilder" /> class.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="user">The user.</param>
        /// <param name="graphField">The graph field.</param>
        /// <param name="schema">The schema.</param>
        /// <param name="graphMethod">The metadata describing the method/functon to be invoked by a resolver.</param>
        public FieldContextBuilder(
            IServiceProvider serviceProvider,
            ClaimsPrincipal user,
            IGraphField graphField,
            ISchema schema,
            IGraphMethod graphMethod)
        {
            _schema            = Validation.ThrowIfNullOrReturn(schema, nameof(schema));
            _graphField        = Validation.ThrowIfNullOrReturn(graphField, nameof(graphField));
            _user              = Validation.ThrowIfNullOrReturn(user, nameof(user));
            _messageCollection = new GraphMessageCollection();

            this.ServiceProvider = Validation.ThrowIfNullOrReturn(serviceProvider, nameof(serviceProvider));

            Type expectedInputType = null;

            if (!Validation.IsCastable <GraphDirective>(graphMethod.Parent.ObjectType) &&
                !Validation.IsCastable <GraphController>(graphMethod.Parent.ObjectType))
            {
                expectedInputType = graphMethod.Parent.ObjectType;
            }

            var metaData = new MetaDataCollection();

            _mockRequest           = new Mock <IGraphFieldRequest>();
            _mockInvocationContext = new Mock <IGraphFieldInvocationContext>();

            // fake the request for the field data (normally generated by the primary query exeuction context)
            var id = Guid.NewGuid().ToString("N");

            _mockRequest.Setup(x => x.Id).Returns(id);
            _mockRequest.Setup(x => x.Origin).Returns(SourceOrigin.None);
            _mockRequest.Setup(x => x.Items).Returns(metaData);
            _mockRequest.Setup(x => x.Field).Returns(_graphField);
            _mockRequest.Setup(x => x.InvocationContext).Returns(_mockInvocationContext.Object);

            _mockInvocationContext.Setup(x => x.ExpectedSourceType).Returns(expectedInputType);
            _mockInvocationContext.Setup(x => x.Field).Returns(_graphField);
            _mockInvocationContext.Setup(x => x.Arguments).Returns(_arguments);
            _mockInvocationContext.Setup(x => x.Name).Returns(_graphField.Name);
            _mockInvocationContext.Setup(x => x.Directives).Returns(new List <IDirectiveInvocationContext>());
            _mockInvocationContext.Setup(x => x.ChildContexts).Returns(new FieldInvocationContextCollection());
            _mockInvocationContext.Setup(x => x.Origin).Returns(SourceOrigin.None);

            this.GraphMethod = new Mock <IGraphMethod>();
            this.GraphMethod.Setup(x => x.Parent).Returns(graphMethod.Parent);
            this.GraphMethod.Setup(x => x.ObjectType).Returns(graphMethod.ObjectType);
            this.GraphMethod.Setup(x => x.ExpectedReturnType).Returns(graphMethod.ExpectedReturnType);
            this.GraphMethod.Setup(x => x.Method).Returns(graphMethod.Method);
            this.GraphMethod.Setup(x => x.IsAsyncField).Returns(graphMethod.IsAsyncField);
            this.GraphMethod.Setup(x => x.Name).Returns(graphMethod.Name);
            this.GraphMethod.Setup(x => x.InternalFullName).Returns(graphMethod.InternalFullName);
            this.GraphMethod.Setup(x => x.InternalName).Returns(graphMethod.InternalName);
            this.GraphMethod.Setup(x => x.Route).Returns(graphMethod.Route);
            this.GraphMethod.Setup(x => x.Arguments).Returns(graphMethod.Arguments);
        }
        /// <summary>
        /// Adds the new field to the interface and to any object types associated with the interface.
        /// </summary>
        /// <param name="interfaceType">Type of the interface.</param>
        /// <param name="newField">The new field.</param>
        private void AddInterfaceField(IInterfaceGraphType interfaceType, IGraphField newField)
        {
            this.EnsureInterfaceIsTracked(interfaceType);

            interfaceType.Extend(newField);
            foreach (var objectType in _graphTypesByInterface[interfaceType])
            {
                objectType.Extend(newField);
            }
        }
        /// <summary>
        /// Attempts to retrieve a default source object for the given field.
        /// </summary>
        /// <param name="field">The expected data type of the field .</param>
        /// <param name="result">The result object populated with the result.</param>
        /// <returns><c>true</c> a source entry is found, <c>false</c> otherwise.</returns>
        public bool TryRetrieveSource(IGraphField field, out object result)
        {
            result = null;
            if (field == null || !_actionSources.ContainsKey(field.Route))
            {
                return(false);
            }

            result = _actionSources[field.Route];
            return(true);
        }
 /// <summary>
 /// Adds the field extension to the associated graph type if possible. If the type is an interface the field is also
 /// added to any graph types that implement the interface. The field is also added to the tracker such that if any
 /// future graph types are added to this instance, that also implement the interface, the field is automatically added to them as well.
 /// If the graph type cannot accept new fields the addition is ignored and no exception is thrown.
 /// </summary>
 /// <param name="graphType">The graph type that will accept the new field.</param>
 /// <param name="newField">The new field to add.</param>
 public void AddFieldExtension(IGraphType graphType, IGraphField newField)
 {
     if (graphType is IInterfaceGraphType interfaceType)
     {
         this.AddInterfaceField(interfaceType, newField);
     }
     else if (graphType is IExtendableGraphType extendableType)
     {
         extendableType.Extend(newField);
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="BatchBuilder{TSource, TResult, TKey}"/> class.
 /// </summary>
 /// <param name="field">The field for witch this batch is being produced.</param>
 /// <param name="sourceData">The source data.</param>
 /// <param name="resultData">The result data.</param>
 /// <param name="sourceKeySelector">The source key selector.</param>
 /// <param name="resultKeySelector">The result key selector.</param>
 public BatchBuilder(
     IGraphField field,
     IEnumerable <TSource> sourceData,
     IEnumerable <TResult> resultData,
     Func <TSource, TKey> sourceKeySelector,
     Func <TResult, IEnumerable <TKey> > resultKeySelector)
 {
     this.Field             = field;
     this.SourceData        = sourceData;
     this.ResultData        = resultData;
     this.SourceKeySelector = sourceKeySelector;
     this.ResultKeySelector = resultKeySelector;
 }
        /// <summary>
        /// Adds the field extension to the queue such that if a graph type associated with the supplied master type is added to the schema,
        /// then the new graph field is automatically added to the new graph type.
        /// </summary>
        /// <param name="masterType">The master type that, if added to the schema, will trigger the addition of this field to its associated <see cref="IGraphType"/>.</param>
        /// <param name="field">The field.</param>
        public void EnQueueField(Type masterType, IGraphField field)
        {
            if (!_unregisteredFieldExtensions.TryGetValue(masterType, out var fieldSet))
            {
                fieldSet = new HashSet <UnregisteredGraphField>(UnregisteredGraphField.Comparer);
                _unregisteredFieldExtensions.TryAdd(masterType, fieldSet);
            }

            var unregisteredField = new UnregisteredGraphField(field, masterType);

            fieldSet.Add(unregisteredField);
            this.FieldCount += 1;
        }
 /// <summary>
 /// Adds a default source for a controller action that can be used as an input when no other source is available.
 /// </summary>
 /// <param name="field">The field representing the controller action.</param>
 /// <param name="sourceData">The source data to store with this context.</param>
 public void AddSource(IGraphField field, object sourceData)
 {
     if (field != null && _sourceTemplateTypes.HasFlag(field.FieldSource))
     {
         lock (_actionSources)
         {
             if (_actionSources.ContainsKey(field.Route))
             {
                 _actionSources[field.Route] = sourceData;
             }
             else
             {
                 _actionSources.Add(field.Route, sourceData);
             }
         }
     }
 }
Пример #10
0
        /// <summary>
        /// Validates the specified node to ensure it is "correct" in the context of the rule doing the valdiation.
        /// </summary>
        /// <param name="context">The validation context encapsulating a <see cref="SyntaxNode" /> that needs to be validated.</param>
        /// <returns><c>true</c> if the node is valid, <c>false</c> otherwise.</returns>
        public override bool Execute(DocumentConstructionContext context)
        {
            var node = (FieldNode)context.ActiveNode;

            // the '__typename' field is a known static quantity that requires no special rule processing or validation
            // it just exists or it doesn't and would be valid on any graph type returning it.
            // Group the appropriate logic for this metafield here to account for the allowed exception in spec rule 5.3.1
            // where unions can contain a field reference for '__typename'
            var allTypes = context.DocumentContext.Schema.KnownTypes.ExpandAbstractType(context.GraphType);

            foreach (var graphType in allTypes)
            {
                if (graphType == null)
                {
                    continue;
                }

                IGraphField field = null;
                if (graphType is IGraphFieldContainer fieldContainer)
                {
                    field = fieldContainer.Fields.FindField(node.FieldName.ToString());
                }

                if (field == null)
                {
                    // if the graph type doesnt contain fields (scalar or enum?) this its an error.
                    // this shouldnt happen because of schema building and validation but just in case...
                    this.ValidationError(
                        context,
                        $"The graph type '{graphType.Name}' does not contain a field named '{node.FieldName.ToString()}'.");

                    continue;
                }

                var fieldSelection = new FieldSelection(node, field, graphType);
                context.AddDocumentPart(fieldSelection);
            }

            return(true);
        }
Пример #11
0
        /// <summary>
        /// Registers the extension field to the <see cref="IObjectGraphType" /> corrisponding to the supplied
        /// concrete type. If a matching graph type cannot be found for the concrete type supplied, the field
        /// is queued for when it is registered.
        /// </summary>
        /// <param name="masterType">The master type that, once added to the schema, will trigger that addition of this field.</param>
        /// <param name="field">The field that will be added to the graph type associated with the master type.</param>
        public void EnsureGraphFieldExtension(Type masterType, IGraphField field)
        {
            Validation.ThrowIfNull(masterType, nameof(masterType));
            Validation.ThrowIfNullOrReturn(field, nameof(field));

            var graphType = _concreteTypes.FindGraphType(masterType);

            if (graphType != null)
            {
                if (!(graphType is IExtendableGraphType))
                {
                    throw new GraphTypeDeclarationException(
                              $"Fatal error. The graph type '{graphType.Name}' of type '{graphType.Kind.ToString()}' does not implement '{typeof(IExtendableGraphType).FriendlyName()}' " +
                              $"and cannot be extended with the new field '{field.Name}'.");
                }

                _extendableGraphTypeTracker.AddFieldExtension(graphType, field);
                return;
            }

            _typeQueue.EnQueueField(masterType, field);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldInvocationContext" /> class.
        /// </summary>
        /// <param name="expectedSourceType">Expected type of the source.</param>
        /// <param name="name">The name to apply to this data set once resolution is complete.</param>
        /// <param name="field">The field.</param>
        /// <param name="origin">The origin, in the source text, that this context was generated from.</param>
        /// <param name="directives">The directives parsed from a query document that are to be executed as part of this context.</param>
        public FieldInvocationContext(
            Type expectedSourceType,
            string name,
            IGraphField field,
            SourceOrigin origin,
            IEnumerable <IDirectiveInvocationContext> directives = null)
        {
            this.Name  = Validation.ThrowIfNullWhiteSpaceOrReturn(name, nameof(name));
            this.Field = Validation.ThrowIfNullOrReturn(field, nameof(field));
            this.ExpectedSourceType = expectedSourceType;
            this.Origin             = origin;
            this.ChildContexts      = new FieldInvocationContextCollection();
            this.Arguments          = new InputArgumentCollection();

            var list = new List <IDirectiveInvocationContext>();

            if (directives != null)
            {
                list.AddRange(directives);
            }
            this.Directives = list;
        }
Пример #13
0
 /// <summary>
 /// Extends this graph type by adding a new field to its collection. An exception may be thrown if
 /// a field with the same name already exists.
 /// </summary>
 /// <param name="newField">The new field.</param>
 public void Extend(IGraphField newField)
 {
     this.GraphFieldCollection.AddField(newField);
 }
 /// <summary>
 /// Adds the <see cref="IGraphField" /> to the collection.
 /// </summary>
 /// <param name="field">The field to add.</param>
 /// <returns>IGraphTypeField.</returns>
 public IGraphField AddField(IGraphField field)
 {
     Validation.ThrowIfNull(field, nameof(field));
     _fields.Add(field.Name, field);
     return(field);
 }
Пример #15
0
 /// <summary>
 /// Finds the graph type, if any, associated with the given field.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns>IGraphType.</returns>
 public IGraphType FindGraphType(IGraphField field)
 {
     return(this.FindGraphType(field?.TypeExpression?.TypeName));
 }
Пример #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BatchBuilder{TSource, TKey}" /> class.
 /// </summary>
 /// <param name="field">The field for witch this batch is being produced.</param>
 /// <param name="sourceData">The source data.</param>
 /// <param name="sourceKeySelector">A function to extract a single key value from each source item.</param>
 public BatchBuilder(IGraphField field, IEnumerable <TSource> sourceData, Func <TSource, TKey> sourceKeySelector)
     : base(field, sourceData, null, sourceKeySelector, null)
 {
 }
Пример #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BatchBuilder" /> class.
 /// </summary>
 /// <param name="field">The field for witch this batch is being produced.</param>
 public BatchBuilder(IGraphField field)
     : base(field, null, null, null, null)
 {
 }
 /// <summary>
 /// Extends this graph type by adding a new field to its collection. An exception may be thrown if
 /// a field with the same name already exists.
 /// </summary>
 /// <param name="newField">The new field.</param>
 public void Extend(IGraphField newField)
 {
     throw new GraphTypeDeclarationException($"Introspection type '{this.Name}' cannot be extended");
 }
 /// <summary>
 /// Determines whether the specified field has an item defined in this collection.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns><c>true</c> if the specified field has a defined value; otherwise, <c>false</c>.</returns>
 public bool ContainsKey(IGraphField field)
 {
     return(field?.Route != null && _actionSources.ContainsKey(field.Route));
 }
Пример #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="IntrospectedField" /> class.
 /// </summary>
 /// <param name="field">The field itself.</param>
 /// <param name="introspectedType">The introspected object representing the graph type returned
 /// by this field.</param>
 public IntrospectedField(IGraphField field, IntrospectedType introspectedType)
 {
     this.IntrospectedGraphType = Validation.ThrowIfNullOrReturn(introspectedType, nameof(introspectedType));
     _field = Validation.ThrowIfNullOrReturn(field, nameof(field));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="UnregisteredGraphField" /> class.
 /// </summary>
 /// <param name="field">The field to register.</param>
 /// <param name="concreteType">The concrete type representing the graph type to which this field should
 /// be added.</param>
 public UnregisteredGraphField(IGraphField field, Type concreteType)
 {
     this.Field        = Validation.ThrowIfNullOrReturn(field, nameof(field));
     this.ConcreteType = Validation.ThrowIfNullOrReturn(concreteType, nameof(concreteType));
 }
Пример #22
0
 /// <summary>
 /// Extends the specified new field.
 /// </summary>
 /// <param name="newField">The new field.</param>
 public void Extend(IGraphField newField)
 {
     _fieldSet.AddField(newField);
 }