Esempio n. 1
0
 public static bool HasCustomResolver(this GraphField field)
 {
     Guard.ArgumentNotNull(field, nameof(field));
     return(field.Properties.TryGetValue(GraphDefaults.PropertyNames.HasCustomResolvers, out var value)
         ? (bool)value
         : false);
 }
Esempio n. 2
0
        private IGraphType CreateGraphType(OperationType operationType, IEnumerable <GraphOperationDescriptor> operations)
        {
            var graphType = new GraphType(operationType);

            if (operations == null)
            {
                return(graphType);
            }
            foreach (var operation in operations)
            {
                var resolver = new OperationResolver(operation, _binderProvider);
                var type     = _graphTypeProvider.GetGraphType(operation.MethodInfo.ReturnType, null, null);

                var field = new GraphField(operation.Name, type, typeof(void), resolver);
                foreach (var parameter in operation.Parameters.Values)
                {
                    if (!parameter.IsGraphArgument)
                    {
                        continue;
                    }
                    var parameterGraphType = _graphTypeProvider.GetGraphType(parameter.ParameterInfo.ParameterType, parameter.IsRequired, null);
                    field.AddArgument(new NamedGraphType(parameter.ArgumentName, parameterGraphType));
                }

                graphType.AddField(typeof(void), field);
            }
            return(graphType);
        }
Esempio n. 3
0
        /// <summary>
        /// Generates the query result class generator.
        /// </summary>
        /// <param name="selection">The <see cref="T:Dora.GraphQL.Selections.IFieldSelection" /> represents the selection node.</param>
        /// <param name="field">The <see cref="T:Dora.GraphQL.GraphTypes.GraphField" /> specific to the selection node.</param>
        /// <returns>
        /// The generated query result class.
        /// </returns>
        public Type Generate(IFieldSelection selection, GraphField field)
        {
            _log4GenerateQueryResultType(_logger, DateTimeOffset.Now, field.GraphType.Type.AssemblyQualifiedName, null);
            var assemblyName    = new AssemblyName($"QueryResult{GetSurffix()}");
            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            var moduleBuilder   = assemblyBuilder.DefineDynamicModule($"{assemblyName}.dll");

            return(Generate(selection, field, moduleBuilder));
        }
Esempio n. 4
0
        private Type Generate(IFieldSelection selection, GraphField graphField, ModuleBuilder moduleBuilder)
        {
            var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final;
            var typeName         = $"{graphField.GraphType.Type.Name}{GetSurffix()}";
            var typeBuilder      = moduleBuilder.DefineType(typeName, TypeAttributes.Public);

            foreach (IFieldSelection subSelection in selection.SelectionSet)
            {
                var  subField  = graphField.GraphType.Fields.Values.Single(it => it.Name == subSelection.Name);
                var  fieldName = $"_{subSelection.Name}";
                Type propertyType;
                if (subSelection.SelectionSet.Count > 0)
                {
                    if (subField.GraphType.IsEnumerable)
                    {
                        var elementType = Generate(subSelection, subField, moduleBuilder);
                        propertyType = typeof(List <>).MakeGenericType(elementType);
                    }
                    else
                    {
                        propertyType = Generate(subSelection, subField, moduleBuilder);
                    }
                }
                else
                {
                    if (subField.GraphType.IsEnumerable)
                    {
                        propertyType = typeof(List <>).MakeGenericType(subField.GraphType.Type);
                    }
                    else
                    {
                        propertyType = subField.GraphType.Type;
                    }
                }

                var field = typeBuilder.DefineField(fieldName, propertyType, FieldAttributes.Private);

                var get = typeBuilder.DefineMethod($"get_{subSelection.Name}", methodAttributes, propertyType, Type.EmptyTypes);
                var il  = get.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);
                il.Emit(OpCodes.Ret);

                var set = typeBuilder.DefineMethod($"set_{subSelection.Name}", methodAttributes, typeof(void), new Type[] { propertyType });
                il = set.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Stfld, field);
                il.Emit(OpCodes.Ret);

                var pb = typeBuilder.DefineProperty(subSelection.Name, PropertyAttributes.None, propertyType, Type.EmptyTypes);
                pb.SetGetMethod(get);
                pb.SetSetMethod(set);
            }
            return(typeBuilder.CreateTypeInfo());
        }
Esempio n. 5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GraphContext"/> class.
 /// </summary>
 /// <param name="operationName">Name of the operation.</param>
 /// <param name="operationType">Type of the operation.</param>
 /// <param name="operation">The operation.</param>
 /// <param name="requestServices">The request services.</param>
 public GraphContext(string operationName, OperationType operationType, GraphField operation, IServiceProvider requestServices)
 {
     OperationName   = operationName;
     OperationType   = operationType;
     Operation       = Guard.ArgumentNotNull(operation, nameof(operation));
     RequestServices = Guard.ArgumentNotNull(requestServices, nameof(requestServices));
     Arguments       = new Dictionary <string, NamedGraphType>();
     SelectionSet    = new Collection <ISelectionNode>();
     Variables       = new Dictionary <string, object>();
     Properties      = new Dictionary <string, object>();
 }
        /// <summary>
        /// Creates graph field from <paramref name="graph"/>
        /// </summary>
        /// <param name="graph"></param>
        /// <returns>Graph field</returns>
        public IGraphField CreateGraphField(IGraph graph)
        {
            if (graph is Graph2D graph2D)
            {
                var graphField = new GraphField(graph2D.Width, graph2D.Length);
                graph.ForEach(graphField.Add);

                return(graphField);
            }

            throw new ArgumentException(nameof(graph));
        }
        private static bool IncludeAllMembers(IFieldSelection fieldSelection, GraphField field)
        {
            var fieldNames         = field.GraphType.Fields.Values.Select(it => it.Name).Distinct().ToArray();
            var selectedFieldNames = fieldSelection.SelectionSet.OfType <IFieldSelection>().Select(it => it.Name).Distinct().ToArray();
            var invalidFieldNames  = selectedFieldNames.Except(fieldNames);

            if (invalidFieldNames.Any())
            {
                throw new GraphException($"Specified field(s) '{string.Join(", ", invalidFieldNames)}' is/are not defined in the GraphType '{field.GraphType.Name}'");
            }
            return(fieldNames.Length == selectedFieldNames.Length);
        }
Esempio n. 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphSchema"/> class.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="mutation">The mutation.</param>
        /// <param name="subsription">The subsription.</param>
        public GraphSchema(IGraphType query, IGraphType mutation, IGraphType subsription)
        {
            Query        = query ?? throw new ArgumentNullException(nameof(query));
            Mutation     = mutation ?? throw new ArgumentNullException(nameof(mutation));
            Subscription = subsription ?? throw new ArgumentNullException(nameof(subsription));
            Fields       = new Dictionary <NamedType, GraphField>();

            var @void    = typeof(void);
            var resolver = FakeResolver.Instance;

            var queryField        = new GraphField(GraphDefaults.GraphSchema.QueryFieldName, query, @void, resolver);
            var mutationField     = new GraphField(GraphDefaults.GraphSchema.MutationFieldName, mutation, @void, resolver);
            var subscriptionField = new GraphField(GraphDefaults.GraphSchema.SubscriptionFieldName, subsription, @void, resolver);

            Fields.Add(new NamedType(GraphDefaults.GraphSchema.QueryFieldName, @void), queryField);
            Fields.Add(new NamedType(GraphDefaults.GraphSchema.MutationFieldName, @void), mutationField);
            Fields.Add(new NamedType(GraphDefaults.GraphSchema.SubscriptionFieldName, @void), subscriptionField);
        }
Esempio n. 9
0
        public static bool SetHasCustomResolverFlags(this GraphField field)
        {
            Guard.ArgumentNotNull(field, nameof(field));
            bool?flag = null;

            if (field.Resolver is MethodResolver)
            {
                flag = true;
            }
            foreach (var subField in field.GraphType.Fields.Values)
            {
                if (SetHasCustomResolverFlags(subField))
                {
                    flag = true;
                }
            }
            if (flag == true)
            {
                field.Properties[GraphDefaults.PropertyNames.HasCustomResolvers] = true;
                return(true);
            }
            return(false);
        }
Esempio n. 10
0
        public static bool TryGetGetField(this IDictionary <NamedType, GraphField> fields, Type type, string name, out GraphField field)
        {
            if (fields.TryGetValue(new NamedType(name, type), out field))
            {
                return(true);
            }

            var baseType = type.BaseType;

            if (baseType != null && TryGetGetField(fields, baseType, name, out field))
            {
                return(true);
            }

            foreach (var @interface in type.GetInterfaces())
            {
                if (TryGetGetField(fields, @interface, name, out field))
                {
                    return(true);
                }
            }

            return((field = null) != null);
        }
Esempio n. 11
0
 public static bool TryGetGetField(this IDictionary <NamedType, GraphField> fields, object container, string name, out GraphField field)
 {
     Guard.ArgumentNotNull(container, nameof(container));
     return(fields.TryGetGetField(container.GetType(), name, out field));
 }
Esempio n. 12
0
 /// <summary>
 /// Adds a new the field in the given <see cref="IGraphType"/>.
 /// </summary>
 /// <param name="graphType">The <see cref="IGraphType"/> in which the new field is added.</param>
 /// <param name="containerType">The CLR type in which the added field is defined.</param>
 /// <param name="graphField">The <see cref="GraphField"/> to add.</param>
 /// <returns>The given <see cref="IGraphType"/>.</returns>
 public static IGraphType AddField(this IGraphType graphType, Type containerType, GraphField graphField)
 {
     Guard.ArgumentNotNull(graphType, nameof(graphType));
     Guard.ArgumentNotNull(containerType, nameof(containerType));
     Guard.ArgumentNotNull(graphField, nameof(graphField));
     graphType.Fields.Add(new NamedType(graphField.Name, containerType), graphField);
     return(graphType);
 }
Esempio n. 13
0
 public static GraphField AddArgument(this GraphField field, NamedGraphType argument)
 {
     Guard.ArgumentNotNull(field, nameof(field));
     field.Arguments.Add(argument.Name, argument);
     return(field);
 }
        public static bool SetIncludeAllFieldsFlags(
            this IFieldSelection selection,
            GraphField graphField,
            IQueryResultTypeGenerator typeGenerator,
            ref bool generateQueryResultType,
            out bool isSubQueryTree)
        {
            Guard.ArgumentNotNull(selection, nameof(selection));
            Guard.ArgumentNotNull(graphField, nameof(graphField));

            EnsureSpecifyRequiredArguments(selection, graphField);

            isSubQueryTree = true;

            bool?flags = null;

            if (graphField.HasCustomResolver() || selection.Directives.Any() || selection.SelectionSet.Any(it => it is IFragment))
            {
                generateQueryResultType = false;
                isSubQueryTree          = false;
                flags = false;
            }

            var subFieldSelections = selection.SelectionSet.OfType <IFieldSelection>().ToArray();

            foreach (var subSelection in subFieldSelections)
            {
                var subFields = graphField.GraphType.Fields.Values.Where(it => it.Name == subSelection.Name).ToArray();

                if (subFields.Length > 1)
                {
                    throw new GraphException($"{graphField.GraphType.Name} is a union GraphType, please perform query using fragement.");
                }
                if (subFields.Length == 0)
                {
                    throw new GraphException($"Field '{subSelection.Name}' is not defined in the GraphType '{graphField.GraphType.Name}'");
                }
                if (!SetIncludeAllFieldsFlags(subSelection, subFields[0], typeGenerator, ref generateQueryResultType, out var isSubtree))
                {
                    flags = false;
                    if (!isSubtree)
                    {
                        isSubQueryTree = false;
                    }
                }
            }

            var fragements = selection.SelectionSet.OfType <IFragment>().ToArray();

            foreach (var fragement in fragements)
            {
                foreach (IFieldSelection fieldSelection in fragement.SelectionSet)
                {
                    var fields = fragement.GraphType.Fields.Values.Where(it => it.Name == fieldSelection.Name).ToArray();
                    if (fields.Length > 1)
                    {
                        throw new GraphException($"{graphField.GraphType.Name} is a union GraphType, please perform query using fragement.");
                    }
                    if (fields.Length == 0)
                    {
                        throw new GraphException($"Field '{fieldSelection.Name}' is not defined in the GraphType '{fragement.GraphType.Name}'");
                    }

                    if (!SetIncludeAllFieldsFlags(fieldSelection, fields[0], typeGenerator, ref generateQueryResultType, out var isSubtree))
                    {
                        flags = false;
                        if (!isSubtree)
                        {
                            isSubQueryTree = false;
                        }
                    }
                }
            }

            if (isSubQueryTree == false)
            {
                selection.Properties[GraphDefaults.PropertyNames.IsSubQueryTree] = false;
            }
            else
            {
                if (graphField.GraphType.Fields.Any() && generateQueryResultType)
                {
                    selection.Properties[GraphDefaults.PropertyNames.QueryResultType] = typeGenerator.Generate(selection, graphField);
                    selection.Properties[GraphDefaults.PropertyNames.IsSubQueryTree]  = false;
                }
            }

            if (!IncludeAllMembers(selection, graphField) || flags == false)
            {
                selection.Properties[GraphDefaults.PropertyNames.IncludeAllFields] = false;
                return(false);
            }

            selection.Properties[GraphDefaults.PropertyNames.IncludeAllFields] = true;
            return(true);
        }
        private static void EnsureSpecifyRequiredArguments(IFieldSelection fieldSelection, GraphField field)
        {
            var argumentNames = field.Arguments.Values
                                .Where(it => it.GraphType.IsRequired)
                                .Select(it => it.Name)
                                .Except(fieldSelection.Arguments.Keys)
                                .ToArray();

            if (argumentNames.Any())
            {
                throw new GraphException($"The mandatory argument(s) '{string.Join(", ", argumentNames)}' is/are not provided.");
            }
        }