access context in a hosted service

shiqo

I need to access the context from this class so I can check some data from the database but I don't know how to transfer it to the service below:

internal class TimedHostedService : IHostedService, IDisposable
{
    private readonly ILogger _logger;
    private Timer _timer;



    public TimedHostedService(ILogger<TimedHostedService> logger) //context ?
    {

        _logger = logger; 


    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is starting.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(60));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        _logger.LogInformation("Atualização automática");


    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

startup file:

namespace Products
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddCors(o => o.AddPolicy("AllowAllOrigins", builder =>
            {
                builder.AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowAnyOrigin();
            }));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddDbContext<Context>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("LaprDB")));
            services.AddDbContext<ContextUsers>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection")));

            services.AddHostedService<TimedHostedService>();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseCors("AllowAllOrigins");
            app.UseHttpsRedirection();
            app.UseMvc();

        }
    }
}

I searched some solutions with scoped factories but i could not understand any of them. Can someone explain me how can i transfer the context to the TimedHostedService? If you need more info just let me know pls .

Gabriel Luci

A Hosted Service is a singleton, which means that only one instance of that class exists for the life of the application.

A Context is scoped, meaning it's designed to have a very short lifespan (only for a specific "scope", like a single HTTP request). It's not good at staying alive indefinitely (there are db connections involved, which you can't guarantee will stay open for the life of the application, for example).

If you inject a Context into another class, the Context will exist for the life of the instance of that class. For a singleton class, that's the life of the application. So this is why you get the exception you do. .NET Core is telling you: "This isn't going to work the way you think it's going to work"

The solution is here: https://stackoverflow.com/a/48368934/1202807

In short, inject a IServiceScopeFactory, which gives you the power to ask the DI engine to give you a scoped class when needed, then it's up to you to keep it around only as long as you need it.

private readonly IServiceScopeFactory _scopeFactory;

public TimedHostedService(ILogger<TimedHostedService> logger, IServiceScopeFactory scopeFactory)
{
    _logger = logger; 
    _scopeFactory = scopeFactory;
}

Then you get your context like this:

using (var scope = scopeFactory.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<Context>();
    //do what you need
}//scope (and context) gets destroyed here

Old answer (which is wrong here, but applies to other types of classes):

Just put it in your constructor and it'll get injected by dependency injection:

public TimedHostedService(ILogger<TimedHostedService> logger, Context context)
{
    _logger = logger; 
    _context = context;
}

It's the services.AddDbContext() lines that makes them available for dependency injection. Just pick type you want, since you've defined two:

services.AddDbContext<Context>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("LaprDB")));
services.AddDbContext<ContextUsers>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection")));

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

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

why I can't access wcf hosted in windows service?

How to access a file from IIS web service hosted by ServiceHost

How to prevent direct access to API hosted in Azure app service

How do I remotely access self-hosted Nancy service?

Kubernetes - Discover and access another cluster service like self-hosted

Cannot access wcf service hosted on iis from php with soapclient

How to access User in a service context in web API?

WCF Service Hosted in a Windows Service

Allow access to windows service hosted WCF services only to one ASP MVC app in Azure

Can't access a database from a WCF Data Service hosted in an ASP NET App

How to access a web service hosted on my AWS work space from internet?

Service fabric hosted Asp.net WebApi Container application : 403 - Forbidden : Access is denied. on local cluster

Can I use Service Principal to authenticate an application that is not hosted in Azure using role-based access control?

API call from Azure App Service to API hosted on Azure VM --Error An attempt was made to access a socket in a way forbidden by its access permissions

Getting Dependency Injection of a hosted service

dbContext is Disposed in a Time Hosted Service

WCF Service hosted in Windows Service hangs on stop

Windows Service vs Hosted WCF Service

WCF Application hosted service not appearing in Service Manager

External access for minikube hosted in Azure

Access SignalR Hub Context.Items from an singleton service in ASP.NET Core

How to reference a hosted service in .Net Core 3?

IIS hosted WCF service is not able to start a process

Blazor: How to get the hosted service instance?

Unable to consume WCF service (hosted in IIS )

Authentication against ADFS with WCF hosted on Windows service

SignalR self hosted windows service, listening for messages

Self-Hosted Web service no loading