ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.26k stars 746 forks source link

Minimal DataLoaders - Support generic type in the generated dataLoaders #7380

Closed joel-dev-qc closed 3 months ago

joel-dev-qc commented 3 months ago

Product

Hot Chocolate

Is your feature request related to a problem?

This is a feature request related to the minimal DataLoadersusing the automatic registration from the HotChocolate.Type.Analyzers package.

The generation doesn't work as expected when the original DataLoaderuses generic types.

Here is an example of a Minimal DataLoader

public class LookupDataLoaders
{
    [DataLoader]
    public static async Task<IReadOnlyDictionary<int, TEnum>> GetLookupByIdBatchAsync<TEnum>(
        IReadOnlyList<int> keys,
        ILookupRepository lookupRepository,
        CancellationToken cancellationToken)
        where TEnum : struct, Enum
    {
        return await lookupRepository.GetEnumLookupByIdBatch<TEnum>(keys);
    }
}

Here is the generated source code.

namespace MyApp.DataLoaders
{
    public interface ILookupByIdBatchDataLoader : global::GreenDonut.IDataLoader<int, TEnum> { }

    public sealed class LookupByIdBatchDataLoader : global::GreenDonut.BatchDataLoader<int, TEnum>, ILookupByIdBatchDataLoader
    {
        private readonly global::System.IServiceProvider _services;

        public LookupByIdBatchDataLoader(
            global::System.IServiceProvider services,
            global::GreenDonut.IBatchScheduler batchScheduler,
            global::GreenDonut.DataLoaderOptions? options = null)
            : base(batchScheduler, options)
        {
            _services = services ??
                throw new global::System.ArgumentNullException(nameof(services));
        }

        protected override async global::System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyDictionary<int, TEnum>> LoadBatchAsync(
            System.Collections.Generic.IReadOnlyList<int> keys,
            global::System.Threading.CancellationToken ct)
        {
            await using var scope = _services.CreateAsyncScope();
            var p1 = scope.ServiceProvider.GetRequiredService<global::MyApp.Repositories.ILookupRepository>();
            return await MyApp.DataLoaders.LookupDataLoaders.GetLookupByIdBatchAsync(keys, p1, ct).ConfigureAwait(false);
        }
    }
}

The generic type is not referenced in the generated source code.

The solution you'd like

The generic types should be considered and supported when the Generated Code Source is created.

michaelstaib commented 3 months ago

We do not support that ... I will create a compiler error for this.

michaelstaib commented 3 months ago

We will have a look at this after V14 again ... for now we throw a compiler error.