public void Register(ApiSchema schema) { var methods = typeof(TInterface).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); foreach (var methodInfo in methods) { if (methodInfo.Name == nameof(IOperation.Register)) { continue; } var isQuery = methodInfo.CustomAttributes.Any(a => a.AttributeType == typeof(QueryAttribute)); var isMutation = methodInfo.CustomAttributes.Any(a => a.AttributeType == typeof(MutationAttribute)); if (!isQuery && !isMutation) { isQuery = true; } var apiOperation = isQuery ? schema.Query : schema.Mutation; var parameters = methodInfo.GetParameters(); if (parameters.Length != 1) { throw new GraphException($"An operation method must have one input parameter. Operation: {typeof(TInterface).Name}.{methodInfo.Name}"); } var fieldName = methodInfo.Name.ToCamelCase(); var fieldDescription = ""; var queryArguments = GraphArguments.FromModel(parameters[0].ParameterType).GetQueryArguments(); // Add function as operation var returnType = TypeLoader.GetBaseType(methodInfo.ReturnType, out bool isList); schema.MapOutput(returnType, autoMapChildren: true, overwriteMap: false); var graphType = TypeLoader.GetGraphType(methodInfo.ReturnType); apiOperation.Field(graphType, fieldName, fieldDescription, queryArguments, context => { var inputModel = ApiOperation.GetInputFromContext(context, parameters[0].ParameterType); ValidationError.ValidateObject(inputModel); var operationValues = new OperationValues() { Context = context, FieldName = fieldName, Fields = new InputField[0], FunctionAttributes = methodInfo.GetCustomAttributes(true).OfType <Attribute>().ToArray(), Input = inputModel, }; operationValues = schema.Container.GetInstance <ApiSchema>().RunOperationFilters(OperationFilterType.Pre, operationValues); var graphClient = GetGraphClient(); var query = graphClient.AddSelectionQuery(fieldName, inputModel, context.FieldAst.SelectionSet.Selections.OfType <Field>()); var graphOutput = isQuery ? graphClient.RunQueries() : graphClient.RunMutations(); if (graphOutput.HasErrors) { graphOutput.ThrowErrors(); } operationValues.Output = query.Data.ToObject(methodInfo.ReturnType); if (PostOperations.ContainsKey(fieldName)) { operationValues.Output = PostOperations[fieldName](context, fieldName, operationValues.Output); } operationValues = schema.Container.GetInstance <ApiSchema>().RunOperationFilters(OperationFilterType.Post, operationValues); return(operationValues.Output); }); } }