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);
        }