private void MapOutput(Type inputType, Type outputType, bool autoMapChildren, bool overwriteMap, List <string> typeNamesLoaded) { if (TypeLoader.IsBasicType(inputType) || typeNamesLoaded.Contains(inputType.FullName)) { return; } if (!TypeLoader.TypeLoaded(inputType) || overwriteMap) { TypeLoader.AddType(inputType, outputType); } typeNamesLoaded.Add(inputType.FullName); if (autoMapChildren && inputType != typeof(string)) { var filter = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; foreach (var propertyInfo in inputType.GetProperties(filter)) { var propertyBaseType = TypeLoader.GetBaseType(propertyInfo.PropertyType, out bool isList); if (propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsPublic && propertyBaseType.FullName != inputType.FullName) { MapOutput(propertyInfo.PropertyType, autoMapChildren, overwriteMap, typeNamesLoaded); } } } }
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); }