Search code examples
c#dependency-injectiongraphql-dotnet

how to inject a database context in graphql-dotnet


ConfigureServices

services.AddSingleton<IServiceProvider>(c => new FuncServiceProvider(type => c.GetRequiredService(type)));
services.AddDbContext<Context>(options => options.UseSqlServer(configuration.GetConnectionString("Default")));

services.AddSingleton<Query>();
services.AddSingleton<Schema>();

services.AddGraphQL();

Configure

app.UseGraphQL<Schema>();

Query

    public class Query : ObjectGraphType
    {
        public Query(IServiceProvider resolver)
        {
            var db = resolver.GetRequiredService<Context>();

            Name = "query";
            Field<ListGraphType<Types.Note>>("notes", resolve: _ => db.Notes.AsAsyncEnumerable());
        }
    }

executing the GraphQL endpoint results in the following exception

System.InvalidOperationException: Cannot resolve scoped service 'Models.Database.Context' from root provider.

some more details.


Solution

  • Query and Schema should be scoped as well if it wants to take advantage of using a DbContext which is added as scoped by default.

    services.AddDbContext<Context>(options => options.UseSqlServer(configuration.GetConnectionString("Default")));
    
    services.AddScoped<Query>();
    services.AddScoped<Schema>();
    
    services.AddGraphQL()
        .AddGraphTypes(ServiceLifetime.Scoped);;
    

    And the Context should be explicitly injected

    public class Query : ObjectGraphType {
        public Query(Context db) {
            Name = "query";
            Field<ListGraphType<Types.Note>>("notes", resolve: _ => db.Notes.AsAsyncEnumerable());
        }
    }