public virtual void RegisterCommands(IEnumerable <Type> commandHandlerTypes) { foreach (var commandHandlerType in commandHandlerTypes) { var genericType = commandHandlerType.GetInterfaces().Single(x => x.GetTypeInfo().IsAssignableToGenericType(typeof(ICommandHandler <,>)) || x.GetTypeInfo().IsAssignableToGenericType(typeof(IAsyncCommandHandler <,>))); var genericArguments = genericType.GetGenericArguments(); var commandType = genericArguments[0]; var queryResultType = genericArguments[1]; var resultType = genericArguments[1]; if (commandType.GetCustomAttribute <ExposeGraphQLAttribute>() == null) { continue; } var isCollection = resultType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(resultType); if (isCollection) { resultType = resultType.GetGenericArguments()[0]; } var descriptionAttribute = commandType.GetCustomAttribute <DescriptionAttribute>(); var exposeAttribute = commandType.GetCustomAttribute <ExposeGraphQLAttribute>(); var authorizeAttribute = commandType.GetCustomAttribute <AuthorizeAttribute>(); if (exposeAttribute == null) { continue; } IInputObjectGraphType inputGqlType = null; var properties = commandType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => !typeof(IResolveFieldContext).IsAssignableFrom(x.PropertyType)).ToList(); if (properties.Any()) { var inputObjectType = typeof(AutoInputGraphType <>).MakeGenericType(commandType); inputGqlType = (IInputObjectGraphType)_container.GetInstance(inputObjectType); inputGqlType.Description = descriptionAttribute?.Description; } IGraphType resultGqlType = null; if (!_typeCache.ContainsKey(queryResultType) && !BuiltInTypeMappings.Any(x => x.clrType == resultType) && !TypeMappings.Any(x => x.clrType == resultType)) { var resultTypeName = resultType.Name; var returnObjectType = typeof(AutoObjectGraphType <>).MakeGenericType(resultType); resultGqlType = (IGraphType)_container.GetInstance(returnObjectType); resultGqlType.Name = resultTypeName; ListGraphType listGqlType = null; if (isCollection) { var name = resultGqlType.Name; listGqlType = (ListGraphType)Activator.CreateInstance(typeof(ListGraphType <>).MakeGenericType(returnObjectType), null); listGqlType.ResolvedType = resultGqlType; resultGqlType = (IGraphType)listGqlType; // resultGqlType.Name = "ListOf" + name; } RegisterTypeMapping(resultType, returnObjectType); } else if (_typeCache.ContainsKey(queryResultType)) { resultGqlType = _typeCache[queryResultType]; } var arguments = new List <QueryArgument>(); if (inputGqlType != null) { var argument = AllowNullCommand ? new QueryArgument(inputGqlType) : new QueryArgument(new NonNullGraphType(inputGqlType)); argument.Name = "command"; arguments.Add(argument); } var mutationName = exposeAttribute.IsFieldNameSet ? exposeAttribute.FieldName : _commandNameSuffixRegex.Replace(commandType.Name, string.Empty); if (!Mutation.HasField(mutationName)) { var type = new FieldType { Type = resultGqlType == null?BuiltInTypeMappings.Where(x => x.clrType == resultType).Select(x => x.graphType).SingleOrDefault() ?? TypeMappings.Where(x => x.clrType == resultType).Select(x => x.graphType).SingleOrDefault() : null, ResolvedType = resultGqlType, Resolver = new CommandResolver(_container, commandHandlerType, commandType, resultType, GetJsonSerializerSettings()), Name = GetNormalizedFieldName(mutationName), Description = descriptionAttribute?.Description, Arguments = new QueryArguments(arguments) }; type.Metadata[GraphQLExtensions.PermissionsKey] = authorizeAttribute?.Permissions?.ToList(); Mutation.AddField(type); } } }