Search code examples
c#.netgraphqlgraphql-dotnet

Could not load type 'GraphQL.Http.IDocumentWriter' from assembly 'GraphQL, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null'


The error happens when it reaches services.AddGraphQL.

I tried downgrading the version of GraphQL to 2.4 but then FuncServiceProvider stops working.

Here's what I have:

MarketScheme.cs

public class MarketScheme : Schema
{
   public MarketScheme(IServiceProvider provider) : base(provider)
   {
        Query = provider.GetRequiredService<AppQuery>();
   }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<marketContext>();

    services.AddScoped<IMarketRepository, MarketRepository>();

    services.AddScoped<IProductRepository, ProductRepository>();

    services.AddScoped<IServiceProvider>(provider => new FuncServiceProvider(provider.GetRequiredService));

    services.AddScoped<MarketScheme>();

    services.AddGraphQL(options =>
    {
        options.ExposeExceptions = true;
        options.EnableMetrics = true;
    }).AddGraphTypes(ServiceLifetime.Scoped);

    services.AddControllers();
}

Solution

  • There are two parts to this.

    1. The interface GraphQL.Http.IDocumentWriter moved to GraphQL.IDocumentWriter.
    2. JSON serialization was extracted into two different libraries, GraphQL.NewtonsoftJson and GraphQL.SystemTextJson.

    If you are using the server project, you will need to update to 4.x.

    See the 2.x to 3.0 upgrade guide if you have written your own middleware.

    Newtonsoft.Json Example

    using Newtonsoft.Json;
    
    private static async Task ExecuteAsync(HttpContext context, ISchema schema)
    {
        GraphQLRequest request;
        using (var reader = new StreamReader(context.Request.Body))
        using (var jsonReader = new JsonTextReader(reader))
        {
            var ser = new JsonSerializer();
            request = ser.Deserialize<GraphQLRequest>(jsonReader);
        }
    
        var executer = new DocumentExecuter();
        var result = await executer.ExecuteAsync(options =>
        {
            options.Schema = schema;
            options.Query = request.Query;
            options.OperationName = request.OperationName;
            options.Inputs = request.Variables.ToInputs();
        });
    
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = result.Errors?.Any() == true ? (int)HttpStatusCode.BadRequest : (int)HttpStatusCode.OK;
    
        var writer = new GraphQL.NewtonsoftJson.DocumentWriter();
        await writer.WriteAsync(context.Response.Body, result);
    }
    
    public class GraphQLRequest
    {
        public string OperationName { get; set; }
        public string Query { get; set; }
        public Newtonsoft.Json.Linq.JObject Variables { get; set; }
    }
    

    System.Text Example

    using System.Text.Json;
    
    private static async Task ExecuteAsync(HttpContext context, ISchema schema)
    {
        var request = await JsonSerializer.DeserializeAsync<GraphQLRequest>
        (
            context.Request.Body,
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
        );
    
        var executer = new DocumentExecuter();
        var result = await executer.ExecuteAsync(options =>
        {
            options.Schema = schema;
            options.Query = request.Query;
            options.OperationName = request.OperationName;
            options.Inputs = request.Variables.ToInputs();
        });
    
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 200; // OK
    
        var writer = new GraphQL.SystemTextJson.DocumentWriter();
        await writer.WriteAsync(context.Response.Body, result);
    }
    
    public class GraphQLRequest
    {
        public string OperationName { get; set; }
    
        public string Query { get; set; }
    
        [JsonConverter(typeof(GraphQL.SystemTextJson.ObjectDictionaryConverter))]
        public Dictionary<string, object> Variables { get; set; }
    }