tris
tris

Reputation: 1049

Resolve scoped service from singleton service

Is it somehow possible to resolve a scoped service in a singleton service's method being called by a scoped one?

E.g. i have a singleton service "GlobalService" and a scoped one "UserService".

If the UserService executes a method "Job" in "GlobalService", is it somehow possible to get scoped services in this method by using Assembly.GetCallingAssembly()? Otherwise I need to pass all the required parameters.

Thank you ✌

Upvotes: 2

Views: 974

Answers (2)

Bala teja
Bala teja

Reputation: 23

@DeepkaMishra's answer won't work in all scenarios.

I used it myself in blazor webassembly loggingprovider and httpcontext came as null. For more details, read this, just adding quoted text here.

Think of HttpContext as a telephone call. If you pick the phone up when no-one has called then there is no context i.e. it is null. When someone does call then you have a valid context. This is the same principal for a web call. The Configure method in Startup is not a web call and, as such, does not have a HttpContext.

Working solution, I found is provided in this.

 public class PersistedConfigurationService : IPersistedConfigurationService
    {
        private readonly IServiceProvider _serviceProvider;
    
        public PersistedConfigurationService(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
    
        public async Task Foo()
        {
            using (var scope = _serviceProvider.CreateScope())
            {
                //here you can get the scoped service
                 var context = scope.ServiceProvider.GetRequiredService<IPersistedConfigurationDbContext>();
                 // do something with context
            }
        }
    }

Upvotes: 1

Deepak Mishra
Deepak Mishra

Reputation: 3203

Singleton would have one single instance which can be used by your scoped service. Your scoped service method can use singleton service instance.

If you call a singleton service's method, you can get the scoped service object in it. You can use IHttpcontextAccessor to resolve the scoped service instance inside that method.

internal class Singleton
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public Singleton(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }
    public int Job()
    {
        return httpContextAccessor.HttpContext.RequestServices.GetRequiredService<Scoped>().MyProperty;
    }
}

You would need to register these service in Startup's ConfigureServices method:

services.AddHttpContextAccessor();
services.AddScoped<Scoped>();
services.AddSingleton<Singleton>();

Upvotes: 0

Related Questions