graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

Custom IErrorFilter - Unable to resolve service for type XXX

Open cts-tradeit opened this issue 3 years ago • 1 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Have a dependenecy and an ErrorFilter:

class Dependency {}

class ErrorFilter: IErrorFilter {
    public ErrorFilter(Dependency dep) {
        /*omitted*/
    }
   /*omitted*/
}

Have dependency registered

services.AddSingleton<Dependency>();

Have a IRequestExecutorBuilder where you add the ErrorFilter

services.AddGraphQLServer().AddErrorFilter<ErrorFilter>();

Execute a query of your choice and get exception: Unable to resolve service for type Dependency while attempting to activate ErrorFilter.

Neither of these examples below produce the exception:

Example 1

services.AddGraphQLServer();
services.AddErrorFilter<ErrorFilter>();

Example 2

services.AddGraphQLServer().AddErrorFilter(provider => ActivatorUtils.CreateInstance<ErrorFilter>(provider));

I realized the provider is not our AutoFac service provider but your CombinedServiceProvider. Where our AutoFac service provider in in field _first and ServiceProviderEngine (I suppose created from schema's IServiceCollection) in field _second. However from it's implemetation I could not figure out why it should cause any exception as AddErrorFilter<T>() registers the ErrorFilter to both service collections.

Steps to reproduce

Please see example above.

Relevant log output

No response

Additional Context?

No response

Product

Hot Chocolate

Version

12.7.0

cts-tradeit avatar Mar 16 '22 15:03 cts-tradeit

I was struggling with the same problem. I think it cannot resolve because when .AddGraphQLServer().AddErrorFilter<GraphQLErrorFilter>, the custom filter is registered with the first service. Whereas its dependencies are registered in the second service. The dependency graph fails to resolve. By registering directly here, the custom filter is resolved from the second service which has the full graph

thaianhduc avatar Apr 26 '22 08:04 thaianhduc

I have the same problem. any workaround suggestions?

Masoud-mm avatar Oct 16 '22 13:10 Masoud-mm

I have the same problem. any workaround suggestions?

@Masoud-mm I register it directly with the primary container as shown below

// Have to register here in the services, the direct registration on IRequestExecutorBuilder will not work
// It cannot resolve the dependencies pass to the custom filter.
// HotChocolate DI internally is a CombinedServices which has 2 IServiceProvider instances 
// 1) The "applicationServices" as the first, It manages the dependencies of the HotChocolate implementation
// 2) The "service" as the second which is the same as "builder.Services"
// When .AddGraphQLServer().AddErrorFilter<GraphQLErrorFilter>, the custom filter is registered with the first service
// whereas its dependencies are registered in the second service. The dependency graph fails to resolve
// By registering directly here, the custom filter is resolved from the second service which has the full graph
builder.Services.AddErrorFilter<GraphQLErrorFilter>();

thaianhduc avatar Oct 17 '22 03:10 thaianhduc

@thaianhduc Thank you very much, I registered my IError filter implementation manually and now I can get my services inside it

Masoud-mm avatar Oct 17 '22 14:10 Masoud-mm