private static QueryArguments GetPropertyArguments(Type sourceType, MethodInfo methodInfo) { var args = new List <QueryArgument>(); foreach (var parameterInfo in methodInfo.GetParameters()) { if (parameterInfo.ParameterType.IsAssignableFrom(sourceType) || parameterInfo.ParameterType.IsAssignableFrom(typeof(IContainer)) || parameterInfo.ParameterType.IsAssignableFrom(typeof(IEnumerable <Field>)) || typeof(ResolverInfo).IsAssignableFrom(parameterInfo.ParameterType)) { continue; } var parameterGraphType = TypeLoader.GetGraphType(parameterInfo.ParameterType); object defaultValue = null; if (parameterInfo.HasDefaultValue) { defaultValue = parameterInfo.DefaultValue; } else { parameterGraphType = typeof(NonNullGraphType <>).MakeGenericType(parameterGraphType); } var argument = new QueryArgument(parameterGraphType) { Name = parameterInfo.Name.ToCamelCase(), DefaultValue = defaultValue }; args.Add(argument); } return(args.Count > 0 ? new QueryArguments(args) : null); }
public static GraphArguments FromModel(Type modelType) { var arguments = new GraphArguments(); foreach (var propertyInfo in modelType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) { var fieldName = char.ToLower(propertyInfo.Name[0]) + propertyInfo.Name.Substring(1); if (arguments.ContainsKey(fieldName)) { continue; } var argument = new GraphArgument() { Name = fieldName, Type = propertyInfo.PropertyType, GraphType = TypeLoader.GetGraphType(propertyInfo.PropertyType, inputType: true), NonNull = propertyInfo.CustomAttributes.Any(a => a.AttributeType == typeof(RequiredAttribute)) }; if (argument.NonNull) { argument.GraphType = typeof(NonNullGraphType <>).MakeGenericType(argument.GraphType); } arguments.Add(fieldName, argument); LoadChildGraphTypes(propertyInfo.PropertyType); } return(arguments); }
/// <summary> /// This is to load all child properties as Input Types for GraphQL as all arguments must of of input type /// </summary> /// <param name="type"></param> private static void LoadChildGraphTypes(Type type) { if (type == typeof(string) || type == typeof(DateTime)) { return; } foreach (var propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) { TypeLoader.GetGraphType(propertyInfo.PropertyType, inputType: true); LoadChildGraphTypes(propertyInfo.PropertyType); } }
public static void AddField(IContainer container, ComplexGraphType <Object> obj, Type type, PropertyInfo propertyInfo, MethodInfo methodInfo) { if (propertyInfo.PropertyType == typeof(IContainer)) { return; } var fieldType = propertyInfo.PropertyType; var fieldName = StringExtensions.PascalCase(propertyInfo.Name); var fieldDescription = ""; var authFieldName = $"{type.FullName}.{propertyInfo.Name}"; Func <ResolveFieldContext <object>, object> contextResolve; if (methodInfo != null) { // Custom mapping of property contextResolve = context => { AuthorizeProperty(container, authFieldName); return(methodInfo.Invoke(obj, GetArgumentsForMethod(methodInfo, container, context))); }; } else { // 1 to 1 mapping of property to source contextResolve = context => { AuthorizeProperty(container, authFieldName); var properties = context.Source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); var sourceProp = properties.FirstOrDefault(p => p.Name == propertyInfo.Name); if (sourceProp == null) { throw new ArgumentException($"No matching source property found for GraphObject. Type: {type.Name} Property: {propertyInfo.Name}"); } return(sourceProp.GetValue(context.Source)); }; } var graphType = TypeLoader.GetGraphType(fieldType); var nonNull = Enumerable.Any(propertyInfo.CustomAttributes, a => a.AttributeType == typeof(RequiredAttribute)); if (nonNull) { graphType = typeof(NonNullGraphType <>).MakeGenericType(graphType); } obj.Field(graphType, fieldName, fieldDescription, null, contextResolve); container.GetInstance <AuthorizationMap>().AddAuthorization(type, propertyInfo); }
public GraphInterface(IContainer container) { Container = container; Name = typeof(T).Name; if (container != null) { FieldMapper.AddAllFields(Container, this, GetType(), true); } ResolveType = o => { if (o is T) { return((ObjectGraphType)Activator.CreateInstance(TypeLoader.GetGraphType(o.GetType()), Container)); } return(null); }; }
public void AddQuery(string fieldName, Type inputType, Type outputType, Func <object, object> function) { fieldName = fieldName.ToCamelCase(); var fieldDescription = ""; var arguments = GraphArguments.FromModel(inputType); var queryArguments = arguments.GetQueryArguments(); // Add function as operation var graphType = TypeLoader.GetGraphType(outputType); Field(graphType, fieldName, fieldDescription, queryArguments, context => { var inputModel = GetInputFromContext(context, inputType); ValidationError.ValidateObject(inputModel); return(function.Invoke(inputModel)); }); }
public static void AddField(IContainer container, ComplexGraphType <Object> obj, Type type, PropertyInfo propertyInfo, MethodInfo methodInfo) { if (propertyInfo.PropertyType == typeof(IContainer)) { return; } var fieldType = propertyInfo.PropertyType; var fieldName = propertyInfo.Name.ToCamelCase(); var fieldDescription = ""; var authFieldName = $"{type.FullName}.{propertyInfo.Name}"; var sourceType = type.BaseType?.GenericTypeArguments.FirstOrDefault() ?? type; QueryArguments arguments = null; Func <ResolveFieldContext <object>, object> contextResolve; if (methodInfo != null) { arguments = GetPropertyArguments(sourceType, methodInfo); // Custom mapping of property contextResolve = context => { AuthorizeProperty(container, authFieldName); var sourceResolverInfo = container.GetInstance <ResolverInfoManager>().Create(context).First(); var output = methodInfo.Invoke(obj, GetArgumentValues(methodInfo, container, context, sourceResolverInfo)); output = container.GetInstance <ApiSchema>().PropertyFilterManager.Filter(sourceResolverInfo, propertyInfo, authFieldName, output); var baseType = TypeLoader.GetBaseType(output?.GetType(), out var isList); if (output != null && !baseType.IsValueType) { container.GetInstance <ResolverInfoManager>().Create(context, output, sourceResolverInfo); } return(output); }; } else { // 1 to 1 mapping of property to source contextResolve = context => { AuthorizeProperty(container, authFieldName); var properties = context.Source.GetType().GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); var sourceProp = properties.FirstOrDefault(p => p.Name == propertyInfo.Name); if (sourceProp == null) { throw new ArgumentException($"No matching source property found for GraphObject. Type: {type.Name} Property: {propertyInfo.Name}"); } var output = sourceProp.GetValue(context.Source); var sourceResolverInfo = container.GetInstance <ResolverInfoManager>().Create(context).First(); output = container.GetInstance <ApiSchema>().PropertyFilterManager.Filter(sourceResolverInfo, propertyInfo, authFieldName, output); var baseType = TypeLoader.GetBaseType(output?.GetType(), out var isList); if (output != null && !baseType.IsValueType) { container.GetInstance <ResolverInfoManager>().Create(context, output, sourceResolverInfo); } return(output); }; } var graphType = TypeLoader.GetGraphType(fieldType); var nonNull = Enumerable.Any(propertyInfo.CustomAttributes, a => a.AttributeType == typeof(RequiredAttribute)); if (nonNull) { graphType = typeof(NonNullGraphType <>).MakeGenericType(graphType); } var field = obj.Field(graphType, fieldName, fieldDescription, arguments, contextResolve); //field.ResolvedType = (IGraphType)Activator.CreateInstance(graphType); container.GetInstance <AuthorizationMap>().AddAuthorization(type, propertyInfo); }