/// <summary> /// Initializes a new instance of the <see cref="GraphFieldPath"/> class. /// </summary> /// <param name="fullPath">The full path.</param> public GraphFieldPath(string fullPath) { this.Raw = fullPath; // set an initial unknown state of this object this.IsValid = false; this.Path = string.Empty; this.Name = string.Empty; this.RootCollection = GraphCollection.Unknown; var workingPath = GraphFieldPath.NormalizeFragment(this.Raw); // split the path into its fragments List <string> pathFragments = workingPath.Split(new[] { RouteConstants.PATH_SEPERATOR }, StringSplitOptions.None).ToList(); switch (pathFragments[0]) { case RouteConstants.QUERY_ROOT: this.RootCollection = GraphCollection.Query; break; case RouteConstants.MUTATION_ROOT: this.RootCollection = GraphCollection.Mutation; break; case RouteConstants.TYPE_ROOT: this.RootCollection = GraphCollection.Types; break; case RouteConstants.ENUM_ROOT: this.RootCollection = GraphCollection.Enums; break; case RouteConstants.DIRECTIVE_ROOT: this.RootCollection = GraphCollection.Directives; break; } // ensure each fragment matches the naming specification foreach (var fragment in pathFragments.Skip(this.RootCollection == GraphCollection.Unknown ? 0 : 1)) { if (!this.ValidateFragment(fragment)) { return; } } this.Name = pathFragments[pathFragments.Count - 1]; if (pathFragments.Count > 1) { this.Parent = new GraphFieldPath(string.Join(RouteConstants.PATH_SEPERATOR, pathFragments.Take(pathFragments.Count - 1))); } this.IsTopLevelField = pathFragments.Count == 1 || (pathFragments.Count == 2 && this.RootCollection > GraphCollection.Unknown); // e.g. "[query]/name" this.IsValid = this.Name.Length > 0; this.Path = this.GeneratePathString(pathFragments); }
/// <summary> /// Initializes a new instance of the <see cref="SubscriptionMethodGraphField" /> class. /// </summary> /// <param name="fieldName">Name of the field in the type declaration..</param> /// <param name="typeExpression">The meta data about how this type field is implemented.</param> /// <param name="route">The formal route to this field in the object graph.</param> /// <param name="mode">The execution mode of this field.</param> /// <param name="resolver">The resolver.</param> /// <param name="securityPolicies">The security policies.</param> /// <param name="eventName">Alterante name of the event that has been assigned to this field.</param> public SubscriptionMethodGraphField( string fieldName, GraphTypeExpression typeExpression, GraphFieldPath route, Execution.FieldResolutionMode mode = Execution.FieldResolutionMode.PerSourceItem, Interfaces.Execution.IGraphFieldResolver resolver = null, IEnumerable <Security.FieldSecurityGroup> securityPolicies = null, string eventName = null) : base(fieldName, typeExpression, route, mode, resolver, securityPolicies) { this.EventName = eventName; }
/// <summary> /// Initializes a new instance of the <see cref="PropertyGraphField" /> class. /// </summary> /// <param name="fieldName">Name of the field in the public graph.</param> /// <param name="typeExpression">The type expression declaring what type of data this field returns.</param> /// <param name="route">The route to this field in the graph.</param> /// <param name="propertyType">The property metadata.</param> /// <param name="propertyDeclaredName">The name of the property as it was declared on the <see cref="Type"/> (its internal name).</param> /// <param name="mode">The mode in which the runtime will process this field.</param> /// <param name="resolver">The resolver to be invoked to produce data when this field is called.</param> /// <param name="securityPolicies">The security policies that apply to this field.</param> public PropertyGraphField( string fieldName, GraphTypeExpression typeExpression, GraphFieldPath route, Type propertyType, string propertyDeclaredName, FieldResolutionMode mode = FieldResolutionMode.PerSourceItem, IGraphFieldResolver resolver = null, IEnumerable <FieldSecurityGroup> securityPolicies = null) : base(fieldName, typeExpression, route, mode, resolver, securityPolicies) { this.ObjectType = propertyType; this.InternalName = propertyDeclaredName; }
/// <summary> /// Initializes a new instance of the <see cref="MethodGraphField" /> class. /// </summary> /// <param name="fieldName">Name of the field in the graph.</param> /// <param name="typeExpression">The meta data describing the type of data this field returns.</param> /// <param name="route">The formal route to this field in the object graph.</param> /// <param name="mode">The mode in which the runtime will process this field.</param> /// <param name="resolver">The resolver to be invoked to produce data when this field is called.</param> /// <param name="securityPolicies">The security policies that apply to this field.</param> public MethodGraphField( string fieldName, GraphTypeExpression typeExpression, GraphFieldPath route, FieldResolutionMode mode = FieldResolutionMode.PerSourceItem, IGraphFieldResolver resolver = null, IEnumerable <FieldSecurityGroup> securityPolicies = null) { this.Name = fieldName; this.TypeExpression = Validation.ThrowIfNullOrReturn(typeExpression, nameof(typeExpression)); this.Route = Validation.ThrowIfNullOrReturn(route, nameof(route)); this.Arguments = new GraphFieldArgumentCollection(); this.SecurityGroups = securityPolicies ?? Enumerable.Empty <FieldSecurityGroup>(); this.UpdateResolver(resolver, mode); }
/// <summary> /// Creates and adds a new <see cref="IGraphField" /> to the growing collection. /// </summary> /// <param name="fieldName">Name of the field.</param> /// <param name="typeExpression">The item representing how this field returns a graph type.</param> /// <param name="route">The formal route that identifies this field in the object graph.</param> /// <param name="resolver">The resolver used to fulfil requests to this field.</param> /// <param name="securityPolicies">The security policies enforced by this field, if any.</param> /// <returns>IGraphTypeField.</returns> public IGraphField AddField( string fieldName, GraphTypeExpression typeExpression, GraphFieldPath route, IGraphFieldResolver resolver = null, IEnumerable <FieldSecurityGroup> securityPolicies = null) { return(this.AddField(new MethodGraphField( fieldName, typeExpression, route, FieldResolutionMode.PerSourceItem, resolver, securityPolicies))); }
/// <summary> /// Initializes a new instance of the <see cref="VirtualGraphField" /> class. /// </summary> /// <param name="fieldName">Name of the field in the object graph.</param> /// <param name="path">The path segment this virtual field will represent.</param> /// <param name="typeName">The type name to use for the virtual type generated from this route field.</param> public VirtualGraphField(string fieldName, GraphFieldPath path, string typeName) { Validation.ThrowIfNull(path, nameof(path)); Validation.ThrowIfNullWhiteSpace(typeName, nameof(typeName)); this.Name = fieldName; this.Route = Validation.ThrowIfNullOrReturn(path, nameof(path)); this.AssociatedGraphType = new VirtualObjectGraphType(typeName); this.TypeExpression = new GraphTypeExpression(typeName); this.Arguments = new GraphFieldArgumentCollection(); this.Resolver = new GraphRouteFieldResolver(new VirtualResolvedObject(this.TypeExpression.TypeName)); // fields made from controller route parameters have no policies directly unto themselves // any controller class level policies are individually added to fields they declare this.SecurityGroups = Enumerable.Empty <FieldSecurityGroup>(); this.Complexity = 1; this.Mode = FieldResolutionMode.PerSourceItem; }
/// <summary> /// Creates and adds a new <see cref="IGraphField" /> to the growing collection. /// </summary> /// <typeparam name="TSource">The expected type of the source data supplied to the resolver.</typeparam> /// <typeparam name="TReturn">The expected type of data to be returned from this field.</typeparam> /// <param name="fieldName">Name of the field.</param> /// <param name="typeExpression">The item representing how this field returns a graph type.</param> /// <param name="route">The formal route that identifies this field in the object graph.</param> /// <param name="resolver">The resolver used to fulfil requests to this field.</param> /// <param name="description">The description to assign to the field.</param> /// <returns>IGraphTypeField.</returns> public IGraphField AddField <TSource, TReturn>( string fieldName, GraphTypeExpression typeExpression, GraphFieldPath route, Func <TSource, Task <TReturn> > resolver, string description = null) where TSource : class { var field = new MethodGraphField( fieldName, typeExpression, route, FieldResolutionMode.PerSourceItem, new GraphDataValueResolver <TSource, TReturn>(resolver)); field.Description = description; return(this.AddField(field)); }
/// <summary> /// Initializes a new instance of the <see cref="GraphArgumentFieldPath" /> class. /// </summary> /// <param name="parentPath">The parent path.</param> /// <param name="argumentName">Name of the argument.</param> public GraphArgumentFieldPath(GraphFieldPath parentPath, string argumentName) : base(GraphFieldPath.Join(parentPath.Path, argumentName)) { }
/// <summary> /// Initializes a new instance of the <see cref="GraphFieldPath" /> class. /// </summary> /// <param name="collection">The collection the route belongs to.</param> /// <param name="pathSegments">The individual path segments of the route.</param> public GraphFieldPath(GraphCollection collection, params string[] pathSegments) : this(GraphFieldPath.Join(collection, pathSegments)) { }
/// <summary> /// Initializes static members of the <see cref="GraphFieldPath"/> class. /// </summary> static GraphFieldPath() { Empty = new GraphFieldPath(string.Empty); Empty.IsValid = true; }
/// <summary> /// Joins a parent and child route segments under the top level field type provided. /// </summary> /// <param name="fieldType">Type of the field to prepend a root key to the path.</param> /// <param name="routeSegments">The route segments to join.</param> /// <returns>System.String.</returns> public static string Join(GraphCollection fieldType, params string[] routeSegments) { return(GraphFieldPath.Join(fieldType.ToRouteRoot().AsEnumerable().Concat(routeSegments).ToArray())); }
/// <summary> /// Joins a parent and child route segments under the top level field type provided. /// </summary> /// <param name="routeSegments">The route segments to join.</param> /// <returns>System.String.</returns> public static string Join(params string[] routeSegments) { var fragment = string.Join(RouteConstants.PATH_SEPERATOR, routeSegments); return(GraphFieldPath.NormalizeFragment(fragment)); }
/// <summary> /// Determines whether this instance contains, as a child, the given path. /// </summary> /// <param name="route">The path.</param> /// <returns><c>true</c> if this path contains the supplied path; otherwise, <c>false</c>.</returns> public bool HasChildRoute(GraphFieldPath route) { return((route?.Path?.Length ?? 0) > 0 && route.Path.StartsWith(this.Path)); }
/// <summary> /// Determines whether the given route represents the same path as this route. /// </summary> /// <param name="route">The route.</param> /// <returns><c>true</c> if the routes point to the same location; otherwise, <c>false</c>.</returns> public bool IsSameRoute(GraphFieldPath route) { return((route?.Path?.Length ?? 0) > 0 && route.Path == this.Path); }