Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: WindowServiceSample1.Worker': Cannot consume scoped service 'WindowServiceSample1.Data.ApplicationDbContext' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.)
using WindowServiceSample1;
using WindowServiceSample1.Data;
using Microsoft.EntityFrameworkCore;
IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = "Abc Service New";
})
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("Server=DESKTOP-4NUBQP8\\SQLEXPRESS;Database=MyDatabase;Trusted_Connection=True;"));
})
.Build();
await host.RunAsync();
Worker class code -
namespace WindowServiceSample1
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ApplicationDbContext _db;
public Worker(ILogger<Worker> logger, ApplicationDbContext db)
{
_logger = logger;
_db = db;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Notification item = new Notification();
item.EUID = "test";
item.StoreNumber = "test";
item.NotificationType = "test";
item.Status = "test";
_db.Notifications.Add(item);
await _db.SaveChangesAsync();
_logger.LogWarning("ABC Service running at: {time}", DateTimeOffset.Now);
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
}
}
}
Application DB Context class
namespace WindowServiceSample1.Data
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Notification> Notifications { get; set; }
}
}
CodePudding user response:
As the error shows we should consume scope services in scoped instances to avoid data corruption or threading issue.
You should use Using ServiceScopeFactory to resolve scope instances.
Like this:
public Worker(ILogger<Worker> logger, , IServiceScopeFactory factory )
{
_logger = logger;
_db = factory.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>();
}
}