0

Recently I have been looking at the following StackOverflow question.

There is an answer there suggesting a read at Microsoft's documentation and especially the paragraph Consuming a scoped service in a background task.

In the page there we have parts of the following code:

internal class ConsumeScopedServiceHostedService : IHostedService
{
    ...
    private void DoWork()
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is working.");

        using (var scope = Services.CreateScope())
        {
            var scopedProcessingService = 
                scope.ServiceProvider
                    .GetRequiredService<IScopedProcessingService>();

            scopedProcessingService.DoWork();
        }
    }
    ...    
}

Isn't this a kind of an anti-pattern? To create a scope inside a method and resolve a service from the service provider? This seems like having a kind of a Service locator (correct me if I am wrong).

Steven
  • 166,672
  • 24
  • 332
  • 435
  • Yes, but any DI container usage outside constructor injection is actually a service locator usage. It's okay for this situation, because you need to manually get your scoped implementation. IHostedService doesn't implement scoped injections by security reasons. Only singletons. – Dmitry Grebennikov May 28 '21 at 11:36
  • I might be horribly wrong but last time I needed an instance of an object as above, I used a factory method I had implemented in which I was calling the Activator `CreateInstance` passing the `ServiceProvider` like `ActivatorUtilities.CreateInstance(_serviceProvider)`. That seemed much more correct to me (meaning I had the factory create the instance - outside my implementation). – Efthymios Kalyviotis May 28 '21 at 11:44
  • 1
    This is breaks SOLID D - dependency inversion principle. You need to avoid custom object instantiating. You need to delegate object creation to DI container. The better solution is to use Microsoft example represented in your question. – Dmitry Grebennikov May 28 '21 at 11:52
  • 1
    It is considered the [Service Locator anti-pattern](https://freecontent.manning.com/the-service-locator-anti-pattern/) when the DI Container is used _outside_ the context of the [Composition Root](https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/). When `ConsumeScopedServiceHostedService` is part of your Composition Root, this is fine and it is _not_ considered an anti-pattern. – Steven May 28 '21 at 15:00

1 Answers1

0

In IHostedService no such built in mechanism for get Context and context.HttpContext.RequestServices I think therefor it's not antipattern