Search code examples
asp.net-coreasp.net-core-hosted-services

ASP.NET Core 2.1 Cannot access database context from a hosted service


I am writing an application in asp.net core 2.1 that has hosted service in it. The reason is that every once in a while I need to run some checks on the database.

I am running into some problems. I cannot inject database context in my hosted service since hosted service is a singleton service and database context is scoped service.

I tried to have a work around by creating an additional web API that handles what i need to do and having my hosted service call that API when required. That added an issue of exposing API and having to hard code an absolute URL into my hosted service class, since the relative URL did not work.

To me this whole thing feels like a hack. Perhaps there is a better way of achieving what I need. Therefore, I am here to ask someone for an advice on what are the best practices regarding my issue. Thank you!


Solution

  • To use a scoped object in a IHostedService you have to create dependency injection scope with the IServiceScopeFactory. Within this scope you can use the scoped services. The doc of Consuming a scoped service in a background task has explained it.

    public class TimedHostedService : IHostedService, IDisposable
    {
        private readonly IServiceScopeFactory _scopeFactory;
        private readonly ILogger _logger;
        private Timer _timer;
    
        public TimedHostedService(ILogger<TimedHostedService> logger, IServiceScopeFactory scopeFactory)
        {
            _logger = logger;
            _scopeFactory = scopeFactory;
        }
    
        // Other methods 
    
        private void DoWork(object state)
        {
            _logger.LogInformation("Timed Background Service is working.");
    
            using (var scope = _scopeFactory.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>();
                //Do your stuff with your Dbcontext
                  ...          
            }
        }
    }