public override void OnConfigure(
            IDescriptorContext context,
            IObjectFieldDescriptor descriptor,
            MemberInfo member)
        {
            descriptor.Resolve(async ctx =>
            {
                ICharacter character            = ctx.Parent <ICharacter>();
                ICharacterRepository repository = ctx.Service <ICharacterRepository>();
                //This is injected by the PreProcessing middleware wen enabled...
                var graphQLParams = new GraphQLParamsContext(ctx);

                //********************************************************************************
                //Perform some pre-processed retrieval of data from the Repository...
                //Notice Pagination processing is pushed down to the Repository layer also!

                //Get RepoDb specific mapper for the GraphQL parameter context...
                //Note: It's important that we map to the DB Model (not the GraphQL model).
                var repoDbParams = new GraphQLRepoDbMapper <CharacterDbModel>(graphQLParams);

                //Now we can retrieve the related and paginated data from the Repo...
                var pagedFriends = await repository.GetCharacterFriendsAsync(character.Id, repoDbParams.GetCursorPagingParameters());
                return(new PreProcessedCursorSlice <ICharacter>(pagedFriends));
                //********************************************************************************
            });
        }
        public async Task <IPreProcessedOffsetPageResults <ICharacter> > GetCharactersWithOffsetPagingAsync(
            [Service] ICharacterRepository repository,
            //THIS is now injected by Pre-Processed extensions middleware...
            [GraphQLParams] IParamsContext graphQLParams
            )
        {
            var repoDbParams = new GraphQLRepoDbMapper <CharacterDbModel>(graphQLParams);

            //********************************************************************************
            //Get the data from the database via our lower level data access repository class.
            //NOTE: Selections (e.g. Projections), SortFields, PagingArgs are all pushed
            //       down to the Repository (and underlying Database) layer.
            var charactersPage = await repository.GetOffsetPagedCharactersAsync(
                repoDbParams.GetSelectFields(),
                repoDbParams.GetSortOrderFields(),
                repoDbParams.GetOffsetPagingParameters()
                );

            //With a valid Page/Slice we can return a PreProcessed Cursor Result so that
            //  it will not have additional post-processing in the HotChocolate pipeline!
            //NOTE: Filtering can be applied but ONLY to the results we are now returning;
            //       Because this would normally be pushed down to the Sql Database layer.
            return(charactersPage.AsPreProcessedPageResults());
            //********************************************************************************
        }
        public async Task <PreProcessedCursorSlice <Droid> > GetDroidsPaginatedAsync(
            [Service] ICharacterRepository repository,
            //THIS is now injected by Pre-Processed extensions middleware...
            [GraphQLParams] IParamsContext graphQLParams
            )
        {
            var repoDbParams = new GraphQLRepoDbMapper <CharacterDbModel>(graphQLParams);

            //********************************************************************************
            //Get the data and convert to List() to ensure it's an Enumerable
            //  and no longer using IQueryable to successfully simulate
            //  pre-processed results.
            //NOTE: Selections (e.g. Projections), SortFields, PagingArgs are all pushed
            //       down to the Repository (and underlying Database) layer.
            var charactersSlice = await repository.GetPagedDroidCharactersAsync(
                repoDbParams.GetSelectFields(),
                repoDbParams.GetSortOrderFields() ?? OrderField.Parse(new { Name = Order.Ascending }),
                repoDbParams.GetCursorPagingParameters()
                );

            //With a valid Page/Slice we can return a PreProcessed Cursor Result so that
            //  it will not have additional post-processing in the HotChocolate pipeline!
            //NOTE: Filtering can be applied but ONLY to the results we are now returning;
            //       Because this would normally be pushed down to the Sql Database layer.
            return(charactersSlice.AsPreProcessedCursorSlice());
            //********************************************************************************
        }
        /// <summary>
        /// Gets all Characters for the specified Id values.
        /// </summary>
        /// <param name="ids">The ids of the human to retrieve.</param>
        /// <param name="repository"></param>
        /// <returns>The character.</returns>
        public async Task <IEnumerable <ICharacter> > GetCharactersByIdAsync(
            [Service] ICharacterRepository repository,
            [GraphQLParams] IParamsContext graphQLParams,
            int[] ids
            )
        {
            var repoDbParams = new GraphQLRepoDbMapper <CharacterDbModel>(graphQLParams);
            var characters   = await repository.GetCharactersByIdAsync(repoDbParams.GetSelectFields(), ids);

            return(characters);
        }
        public async Task <IEnumerable <ICharacter> > GetAllCharactersAsync(
            [Service] ICharacterRepository repository,
            [GraphQLParams] IParamsContext graphQLParams
            )
        {
            var repoDbParams = new GraphQLRepoDbMapper <CharacterDbModel>(graphQLParams);

            var sortedCharacters = await repository.GetAllSortedCharactersAsync(
                selectFields : repoDbParams.GetSelectFields(),
                sortFields : repoDbParams.GetSortOrderFields()
                );

            return(sortedCharacters.AsPreProcessedSortResults());
        }