private static void ProcessProperties(IComplexGraphType graphType, IEnumerable <PropertyInfo> properties, bool isInputType = false) { foreach (var property in properties.OrderBy(p => p.Name)) { bool isNotNull = TypeHelper.IsNotNull(property); var propertyGraphType = TypeHelper.GetGraphType(property); if (propertyGraphType != null) { propertyGraphType = GraphTypeConverter.ConvertTypeToGraphType(propertyGraphType, isNotNull, isInputType); propertyGraphType = EnsureList(property.PropertyType, propertyGraphType); } else { propertyGraphType = GraphTypeConverter.ConvertTypeToGraphType(property.PropertyType, isNotNull, isInputType); } var name = StringHelper.GraphName(property.Name); var field = graphType.AddField(new FieldType { Type = propertyGraphType, Name = name, Description = TypeHelper.GetDescription(property) }); field.DefaultValue = TypeHelper.GetDefaultValue(property); field.DeprecationReason = TypeHelper.GetDeprecationReason(property); } }
public static bool TryGetComplexGraph(this FieldType fieldType, out IComplexGraphType complexGraph) { var orAdd = GetOrAdd(fieldType); complexGraph = orAdd.ComplexGraphType; return(complexGraph != null); }
public static FieldType Query <Controller>(this IComplexGraphType graphType, Type returnGraphType, Expression <Func <Controller, object> > methodCall) { var fieldType = ExpressionToFieldTypeGenerator.GenerateFieldType(graphType, methodCall, returnGraphType: returnGraphType); graphType.AddField(fieldType); return(fieldType); }
public static FieldType QueryAsync <Controller>(this IComplexGraphType graphType, string name, Expression <Func <Controller, Task> > methodCall) { var fieldType = ExpressionToFieldTypeGenerator.GenerateAsyncFieldType(graphType, methodCall, name); graphType.AddField(fieldType); return(fieldType); }
private void DeriveFields(GraphTypeInfo typeInfo, IComplexGraphType graphType) { foreach (var field in typeInfo.Fields.Select(DeriveField)) { graphType.AddField(field); } }
private static void ProcessFields(IComplexGraphType graphType, IEnumerable <FieldInfo> fields, bool isInputType = false) { foreach (var field in fields.OrderBy(f => f.Name)) { bool isNotNull = TypeHelper.IsNotNull(field); var fieldGraphType = TypeHelper.GetGraphType(field); if (fieldGraphType != null) { fieldGraphType = GraphTypeConverter.ConvertTypeToGraphType(fieldGraphType, isNotNull, isInputType); fieldGraphType = EnsureList(field.FieldType, fieldGraphType); } else { fieldGraphType = GraphTypeConverter.ConvertTypeToGraphType(field.FieldType, isNotNull, isInputType); } var addedField = graphType.AddField(new FieldType { Type = fieldGraphType, Name = StringHelper.GraphName(field.Name) }); addedField.DeprecationReason = TypeHelper.GetDeprecationReason(field); } }
public static void ApplyProperties <TModelType>(this IComplexGraphType instance) { var type = typeof(TModelType); foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance)) { var fieldAttr = prop.GetCustomAttribute <GraphQLFieldAttribute>(); if (fieldAttr == null) { continue; } try { instance.AddField(new FieldType { Name = fieldAttr.Name ?? prop.Name.FirstCharacterToLower(), Type = fieldAttr.ReturnType ?? prop.PropertyType.ToGraphType(), Resolver = new PropertyResolver(prop), Description = fieldAttr.Description }); } catch (ArgumentOutOfRangeException exception) { throw new NotSupportedException( $"Unable to register field for property {prop.Name}", exception); } } }
static ContentFieldData ToFieldData(IDictionary <string, object> source, IComplexGraphType type) { var result = new ContentFieldData(); foreach (var field in type.Fields) { if (source.TryGetValue(field.Name, out var value)) { if (value is IEnumerable <object> list && field.ResolvedType.Flatten() is IComplexGraphType nestedType) { var array = new JsonArray(list.Count()); foreach (var item in list) { if (item is JsonObject nested) { array.Add(nested); } } result[field.SourceName()] = array; } else { result[field.SourceName()] = JsonGraphType.ParseJson(value); } } } return(result); }
internal static IFilter ResolveFilter <TParentType>( this IComplexGraphType filterType, KeyValuePair <string, object> value, ResolveFieldContext <TParentType> context) { var path = (context.Path ?? new[] { "filter" }).Concat(new[] { value.Key }); var field = filterType.Fields.First(x => x.Name == value.Key); return((IFilter)field.Resolver.Resolve( new ResolveFieldContext { FieldName = field.Name, FieldAst = new Field(null, new NameNode(field.Name)), FieldDefinition = field, ParentType = context.ParentType, Source = value.Value, Schema = context.Schema, Document = context.Document, Fragments = context.Fragments, RootValue = context.RootValue, UserContext = context.UserContext, Operation = context.Operation, Variables = context.Variables, CancellationToken = context.CancellationToken, Metrics = context.Metrics, Errors = context.Errors, Path = path, } )); }
internal static IFilter ResolveFilter( this IComplexGraphType filterType, KeyValuePair <string, object> value, IObjectGraphType parentType, ExecutionContext executionContext) { var field = filterType.Fields.First(x => x.Name == value.Key); return((IFilter)field.Resolver.Resolve( new ResolveFieldContext { FieldName = field.Name, FieldAst = new Field(null, new NameNode(field.Name)), FieldDefinition = field, ParentType = parentType, Source = value.Value, Schema = executionContext.Schema, Document = executionContext.Document, Fragments = executionContext.Fragments, RootValue = executionContext.RootValue, UserContext = executionContext.UserContext, Operation = executionContext.Operation, Variables = executionContext.Variables, CancellationToken = executionContext.CancellationToken, Metrics = executionContext.Metrics, Errors = executionContext.Errors, } )); }
private void AddAssetsQueries(IComplexGraphType assetType) { AddField(new FieldType { Name = "queryAssets", Arguments = CreateAssetQueryArguments(), ResolvedType = new ListGraphType(new NonNullGraphType(assetType)), Resolver = ResolveAsync((c, e) => { var assetQuery = BuildODataQuery(c); return(e.QueryAssetsAsync(assetQuery)); }), Description = "Get assets." }); AddField(new FieldType { Name = "queryAssetsWithTotal", Arguments = CreateAssetQueryArguments(), ResolvedType = new AssetsResultGraphType(assetType), Resolver = ResolveAsync((c, e) => { var assetQuery = BuildODataQuery(c); return(e.QueryAssetsAsync(assetQuery)); }), Description = "Get assets and total count." }); }
private void AddAssetsQueries(IComplexGraphType assetType) { AddField(new FieldType { Name = "queryAssets", Arguments = CreateAssetQueryArguments(), ResolvedType = new ListGraphType(new NonNullGraphType(assetType)), Resolver = ResolveAsync((c, e) => { var argTake = c.GetArgument("take", 20); var argSkip = c.GetArgument("skip", 0); var argQuery = c.GetArgument("search", string.Empty); return(e.QueryAssetsAsync(argQuery, argSkip, argTake)); }), Description = "Get assets." }); AddField(new FieldType { Name = "queryAssetsWithTotal", Arguments = CreateAssetQueryArguments(), ResolvedType = new AssetsResultGraphType(assetType), Resolver = ResolveAsync((c, e) => { var argTake = c.GetArgument("take", 20); var argSkip = c.GetArgument("skip", 0); var argQuery = c.GetArgument("search", string.Empty); return(e.QueryAssetsAsync(argQuery, argSkip, argTake)); }), Description = "Get assets and total count." }); }
public FieldType AddUnionQueryField <TUnion, TSource>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, Task <IDictionary <Type, IQueryable <object> > > >?resolveAsync = null, IEnumerable <QueryArgument>?arguments = null, string?description = null) where TUnion : UnionGraphType { Guard.AgainstNull(nameof(graph), graph); var field = BuildUnionQueryField <TUnion, TSource>(name, resolveAsync, arguments, description); return(graph.AddField(field)); }
void AddQueryableConnection <TSource, TGraph, TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, IQueryable <TReturn> >?resolve, IEnumerable <QueryArgument>?arguments, int pageSize, string?description) where TGraph : IGraphType where TReturn : class { var builder = ConnectionBuilder.Create <TGraph, TSource>(); builder.Name(name); if (description != null) { builder.Description(description); } builder.PageSize(pageSize).Bidirectional(); if (resolve != null) { builder.Resolve( context => { var efFieldContext = BuildContext(context); var query = resolve(efFieldContext); if (disableTracking) { query = query.AsNoTracking(); } query = includeAppender.AddIncludes(query, context); var names = GetKeyNames <TReturn>(); query = query.ApplyGraphQlArguments(context, names, true); return(query .ApplyConnectionContext( context.First, context.After, context.Last, context.Before, context, context.CancellationToken, efFieldContext.Filters)); }); } // TODO: works around https://github.com/graphql-dotnet/graphql-dotnet/pull/2581/ builder.FieldType.Type = typeof(NonNullGraphType <ConnectionType <TGraph, EdgeType <TGraph> > >); var field = graph.AddField(builder.FieldType); var hasId = keyNames.ContainsKey(typeof(TReturn)); field.AddWhereArgument(hasId, arguments); }
private void HandleField(IComplexGraphType parentType, FieldType field, TypeCollectionContext context, bool applyNameConverter) { // applyNameConverter will be false while processing the three root introspection query fields: __schema, __type, and __typename // // During processing of those three root fields, the NameConverter will be set to the schema's selected NameConverter, // and the field names must not be processed by the NameConverter // // For other introspection types and fields, the NameConverter will be set to CamelCaseNameConverter at the time this // code executes, and applyNameConverter will be true // // For any other fields, the NameConverter will be set to the schema's selected NameConverter at the time this code // executes, and applyNameConverter will be true if (applyNameConverter) { field.Name = NameConverter.NameForField(field.Name, parentType); NameValidator.ValidateName(field.Name); } if (field.ResolvedType == null) { AddTypeIfNotRegistered(field.Type, context); field.ResolvedType = BuildNamedType(field.Type, context.ResolveType); } else { AddTypeIfNotRegistered(field.ResolvedType, context); } if (field.Arguments == null) { return; } foreach (var arg in field.Arguments) { if (applyNameConverter) { arg.Name = NameConverter.NameForArgument(arg.Name, parentType, field); NameValidator.ValidateName(arg.Name, "argument"); } if (arg.ResolvedType != null) { AddTypeIfNotRegistered(arg.ResolvedType, context); continue; } AddTypeIfNotRegistered(arg.Type, context); arg.ResolvedType = BuildNamedType(arg.Type, context.ResolveType); } }
public string PrintFields(IComplexGraphType type) { var fields = type?.Fields .Select(x => new { x.Name, Type = ResolveName(Schema.FindType(x.Type)), Args = PrintArgs(x) }).ToList(); return(string.Join(Environment.NewLine, fields?.Select(f => " {0}{1}: {2}".ToFormat(f.Name, f.Args, f.Type)))); }
public FieldType GenerateFieldType <Controller, ReturnType>(IComplexGraphType graphType, Expression <Func <Controller, ReturnType> > methodCall, string name = null, Type returnGraphType = null) { var fieldInfo = expressionToFieldInfoTransformer.FromExpression(methodCall, typeof(Controller)); var fieldType = fieldInfoToFieldTypeTransformer.TransformToFieldType(fieldInfo, returnGraphType); if (!(name is null)) { fieldType.Name = name; } fieldType.Resolver = fieldInfoResolver.GenerateFieldResolver(graphType, fieldInfo); return(fieldType); }
public FieldType AddQueryField <TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, object>, IQueryable <TReturn> >?resolve = null, Type?graphType = null, IEnumerable <QueryArgument>?arguments = null, string?description = null) where TReturn : class { var field = BuildQueryField(graphType, name, resolve, arguments, description); return(graph.AddField(field)); }
/// <summary> /// Adds the specified fields to the specified graph. /// Skips null fields. /// </summary> public static void AddFields(IComplexGraphType graphType, IEnumerable <FieldType?>?fieldTypes) { if (fieldTypes != null) { foreach (var fieldType in fieldTypes) { if (fieldType != null) { graphType.AddField(fieldType); } } } }
public FieldType AddQueryField <TSource, TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, IQueryable <TReturn> >?resolve = null, Type?itemGraphType = null, IEnumerable <QueryArgument>?arguments = null, string?description = null) where TReturn : class { Guard.AgainstNull(nameof(graph), graph); var field = BuildQueryField(itemGraphType, name, resolve, arguments, description); return(graph.AddField(field)); }
public DelegateToFieldRule( IComplexGraphType graphType, string fieldName, string delegateFieldName, Func <TModel, TDelegateID> idGetter) { ResolvedType = graphType.GetField(fieldName).ResolvedType as IComplexGraphType; if (ResolvedType == null) { throw new Exception($"ResolvedType of an object authorized by {GetType().Name} must be an IComplexGraphType"); } DelegateFieldName = delegateFieldName; IDGetter = idGetter; }
public FieldType AddQueryField <TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, object>, Task <IQueryable <TReturn> > >?resolveAsync = null, Type?graphType = null, IEnumerable <QueryArgument>?arguments = null, string?description = null, bool disableDefaultArguments = false) where TReturn : class { Guard.AgainstNull(nameof(graph), graph); var field = BuildQueryField(graphType, name, resolveAsync, arguments, description, disableDefaultArguments); return(graph.AddField(field)); }
public FieldType AddSingleField <TSource, TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, IQueryable <TReturn> > resolve, Func <ResolveEfFieldContext <TDbContext, TSource>, TReturn, Task>?mutate = null, Type?graphType = null, IEnumerable <QueryArgument>?arguments = null, bool nullable = false, string?description = null) where TReturn : class { var field = BuildSingleField(name, resolve, mutate, arguments, graphType, nullable, description); return(graph.AddField(field)); }
public void AddQueryConnectionField <TSource, TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, IQueryable <TReturn> >?resolve = null, Type?itemGraphType = null, IEnumerable <QueryArgument>?arguments = null, int pageSize = 10, string?description = null) where TReturn : class { itemGraphType ??= GraphTypeFinder.FindGraphType <TReturn>(); var addConnectionT = addQueryableConnection.MakeGenericMethod(typeof(TSource), itemGraphType, typeof(TReturn)); addConnectionT.Invoke(this, new object?[] { graph, name, resolve, arguments, pageSize, description }); }
/// <summary> /// Checks input type received via introspection query for correctness /// </summary> /// <param name="graphType"> /// The type to check /// </param> /// <param name="checkedInputTypes"> /// The types already checked (to limit the recursion) /// </param> /// <returns> /// The list of found errors /// </returns> private static IEnumerable <string> CheckInputGraphType( IComplexGraphType graphType, ICollection <string> checkedInputTypes) { if (checkedInputTypes.Contains(graphType.Name)) { yield break; } checkedInputTypes.Add(graphType.Name); if (graphType.Fields == null || !graphType.Fields.Any()) { yield return($"Input type {graphType.Name} has no fields"); yield break; } foreach (var field in graphType.Fields) { var fieldResolvedType = GetResolvedType(field.ResolvedType); if (fieldResolvedType == null) { yield return($"Input type {graphType.Name} has field {field.Name} of unknown type"); continue; } if (!(fieldResolvedType is ScalarGraphType) && !(fieldResolvedType is IInputGraphType) && !(fieldResolvedType is InputObjectGraphType)) { yield return ($"Field {field.Name} of type {graphType.Name} " + $"has argument {field.Name} has invalid type {fieldResolvedType.Name}"); continue; } var complexGraphType = fieldResolvedType as IComplexGraphType; if (complexGraphType != null) { foreach (var error in CheckInputGraphType(complexGraphType, checkedInputTypes)) { yield return(error); } } } }
public virtual string PrintFields(IComplexGraphType type) { var fields = type?.Fields .Select(x => new { x.Name, Type = ResolveName(x.ResolvedType), Args = PrintArgs(x), Description = Options.IncludeDescriptions ? PrintDescription(x.Description, " ") : string.Empty, Deprecation = Options.IncludeDeprecationReasons ? PrintDeprecation(x.DeprecationReason) : string.Empty, }).ToList(); return(string.Join(Environment.NewLine, fields?.Select( f => "{3} {0}{1}: {2}{4}".ToFormat(f.Name, f.Args, f.Type, f.Description, f.Deprecation)))); }
public void AddQueryConnectionField <TSource, TReturn>( IComplexGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, IQueryable <TReturn> >?resolve = null, Type?itemGraphType = null, IEnumerable <QueryArgument>?arguments = null, int pageSize = 10, string?description = null) where TReturn : class { Guard.AgainstNull(nameof(graph), graph); var connection = BuildQueryConnectionField(name, resolve, pageSize, itemGraphType, description); var field = graph.AddField(connection.FieldType); field.AddWhereArgument(arguments); }
public override string PrintFields(IComplexGraphType type) { var fields = type?.Fields .Where(x => !IsFederatedType(x.ResolvedType.GetNamedType().Name)) .Select(x => new { x.Name, Type = ResolveName(x.ResolvedType), Args = PrintArgs(x), Description = Options.IncludeDescriptions ? PrintDescription(x.Description, " ") : string.Empty, Deprecation = Options.IncludeDeprecationReasons ? PrintDeprecation(x.DeprecationReason) : string.Empty, FederatedDirectives = PrintFederatedDirectivesFromAst(x) }).ToList(); return(string.Join(Environment.NewLine, fields?.Select( f => "{3} {0}{1}: {2}{4}{5}".ToFormat(f.Name, f.Args, f.Type, f.Description, f.Deprecation, f.FederatedDirectives)))); }
public static void Field( this IComplexGraphType obj, string name, IGraphType type, string description = null, QueryArguments arguments = null, Func <IResolveFieldContext, object> resolve = null) { var field = new FieldType { Name = name, Description = description, Arguments = arguments, ResolvedType = type, Resolver = resolve != null ? new FuncFieldResolver <object>(resolve) : null }; obj.AddField(field); }
private static void ProcessMethods(IComplexGraphType graphType, Type type, IEnumerable <MethodInfo> methods) { if (!typeof(GraphType).IsAssignableFrom(type) && !type.IsDefined(typeof(GraphTypeAttribute))) { return; } foreach (var method in methods.OrderBy(m => m.Name)) { if (IsSpecialMethod(method)) { continue; } bool isNotNull = TypeHelper.IsNotNull(method); var returnGraphType = TypeHelper.GetGraphType(method); var methodGraphType = returnGraphType; if (methodGraphType != null) { methodGraphType = GraphTypeConverter.ConvertTypeToGraphType(methodGraphType, isNotNull); methodGraphType = EnsureList(method.ReturnType, methodGraphType); } else { methodGraphType = GraphTypeConverter.ConvertTypeToGraphType(method.ReturnType, isNotNull); } var arguments = new QueryArguments( method.GetParameters() .Where(p => p.ParameterType != typeof(ResolveFieldContext)) .Select(CreateArgument)); // todo: need to fix method execution - not called currently so lower priority graphType.AddField(new FieldType { Type = methodGraphType, Name = StringHelper.GraphName(method.Name), Arguments = arguments, DeprecationReason = TypeHelper.GetDeprecationReason(method), //Resolver = new AsyncFuncFieldResolver(()=>ResolveField(context, field)) }); } }