Cannot Resolve Scoped Service from Root Provider .Net Core 2

Cannot resolve scoped service from root provider .Net Core 2

You registered the IEmailRepository as a scoped service, in the Startup class.
This means that you can not inject it as a constructor parameter in Middleware because only Singleton services can be resolved by constructor injection in Middleware. You should move the dependency to the Invoke method like this:

public ExceptionHandlingMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task Invoke(HttpContext context, IEmailRepository emailRepository)
{
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex, emailRepository);
}
}

Cannot resolve scoped service from root provider when ASPNETCORE_ENVIRONMENT: Development

See Dependency injection in ASP.NET Core - Scope validation:

When the app runs in the Development environment and calls CreateDefaultBuilder to build the host, the default service provider performs checks to verify that:

  • Scoped services aren't resolved from the root service provider.
  • Scoped services aren't injected into singletons.

[...]

Scoped services are disposed by the container that created them. If a scoped service is created in the root container, the service's lifetime is effectively promoted to singleton because it's only disposed by the root container when the app shuts down. Validating service scopes catches these situations when BuildServiceProvider is called.

For more information, see Scope validation.

This feature is new in ASP.NET Core v3. Previous versions of ASP.NET Core lacked this feature.

To me, the downside of this feature is that it is actually disabled by default when you run in production. It should have been on by default in all environments, because it will cause multi-threading issues and memory leaks.

Cannot resolve from root provider because it requires scoped service

As the exception message says, your ProductAPI.IntegrationEvents.EventHandling.OrderCreatedIntegrationEventHandler is not resolved in a scope or is not registered as a scoped service.

Whatever event dispatcher you use ought to begin a scope before resolving the event handler and handling events. And the OrderCreatedIntegrationEventHandler must be registered as a service scoped too.

My guess is that Autofac does not perform any lifetime mismatch checks at startup and that's why it does not throw when you plug in Autofac. This does not mean, that it actually works, only that you hide a potential error. It may come up as an exception the first time you handle an event, or it may be even more severe in that it just uses an the same ProductDbContext over the lifetime of the event handler, which might be singleton.

But note that I havn't used Autofac, only other containers, so I don't know how exactly this library handles such issues.

EDIT 1

This line (260): var handler = _serviceProvider.GetRequiredService(subscription.HandlerType); in the provided source for EventBusRabbitMq needs to be changed to: var handler = scope.ServiceProvicer.GetRequiredService(subscription.HandlerType);.

Inside the scope you should resolve your services using the scope (as opposed to from the root service provider _serviceProvider from which you create your scope).

Cannot resolve scoped service

Cannot resolve scoped service ICommandHandler<CreateUser> from root provider

As the error says, you cannot create a scoped service instance from the root provider. The root provider is the root service provider that exists outside of service scopes. As such, it cannot resolve services that should only be consumed within service scopes.

If you want to resolve a scoped service from the root provider, for example when you are consuming it from a singleton service, you should create a service scope first using the IServiceScopeFactory:

var serviceScopeFactory = _webHost.Services.GetService<IServiceScopeFactory>();
using (var scope = serviceScopeFactory.CreateScope())
{
var handler = (IEventHandler<TEvent>)scope.ServiceProvider.GetService(typeof(IEventHandler<TEvent>))
// …
}

Note that service scopes are supposed to be short lived, and that you need to dispose them afterwards to clean up.


Looking at your implementation, it seems as if you pass your scoped services to some other service in order to subscribe to events. This generally seems like a bad idea since that means that a reference to a scoped service will be kept by a (likely) singleton service for the whole lifetime of the application. This is generally a bad idea (as I said, scoped services are supposed to live only a short time).

You should ask yourself why you need the services to be scoped there, and whether you cannot make them singleton instead. Or if you actually need the subscribe mechanism to be based on the instance (instead of for example just the type, using a factory pattern or something).

Cannot resolve scoped service from root provider. ASP.NET MVC app App

You need to create scope in EnsurePopulated method and then get instance from this scope.

Cannot resolve scoped service from root provider - solution to error?

You need to disable scope verification in the Program class:

public class Program {
...

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseDefaultServiceProvider(options =>
options.ValidateScopes = false)
.Build();
}

Cannot resolve scoped service 'FluentValidation.IValidatorFactory' from root provider

I had quite the same problem in combination with Swashbuckle and it worked when I didn't use the newest releases:

<PackageReference Include="FluentValidation.AspNetCore" Version="9.5.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.6.3" />

Cannot resolve scoped service dbcontext from root provider

As per https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-3.1#per-request-middleware-dependencies, you must inject scoped service in the Invoke method:

public class CustomMiddleware
{
private readonly RequestDelegate _next;

public CustomMiddleware(RequestDelegate next)
{
_next = next;
}

// IMyScopedService is injected into Invoke
public async Task Invoke(HttpContext httpContext, IMyScopedService svc)
{
svc.MyProperty = 1000;
await _next(httpContext);
}
}


Related Topics



Leave a reply



Submit