نحوهی صحیح استفاده از سرویسهای دامنهدار در سرویسهای پسزمینه در داتنت
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۷/۲۸ ۰۹:۴۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
InvalidOperationException: Cannot consume scoped service 'AppDbContext' from singleton 'MyBackgroundService'
public class InactiveUserNotifierService : BackgroundService
{
private readonly IUserRepository _userRepository; // تزریق مستقیم سرویس دامنهدار
public InactiveUserNotifierService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// استفاده از _userRepository در حلقهی پسزمینه
}
}public interface IUserRepository
{
Task<List<User>> GetInactiveUsersAsync();
Task MarkAsNotifiedAsync(User user);
}
public class UserRepository : IUserRepository
{
private readonly AppDbContext _context;
public UserRepository(AppDbContext context)
{
_context = context;
}
public async Task<List<User>> GetInactiveUsersAsync()
{
return await _context.Users
.Where(u => !u.IsActive)
.ToListAsync();
}
public async Task MarkAsNotifiedAsync(User user)
{
user.IsNotified = true;
await _context.SaveChangesAsync();
}
}builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddHostedService<InactiveUserNotifierService>();public class InactiveUserNotifierService : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly ILogger<InactiveUserNotifierService> _logger;
public InactiveUserNotifierService(
IServiceScopeFactory scopeFactory,
ILogger<InactiveUserNotifierService> logger)
{
_scopeFactory = scopeFactory;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("InactiveUserNotifierService started.");
while (!stoppingToken.IsCancellationRequested)
{
try
{
using (var scope = _scopeFactory.CreateScope())
{
var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
var inactiveUsers = await userRepository.GetInactiveUsersAsync();
foreach (var user in inactiveUsers)
{
_logger.LogInformation($"Sending reminder email to {user.Email}");
await userRepository.MarkAsNotifiedAsync(user);
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while notifying inactive users.");
}
await Task.Delay(TimeSpan.FromHours(1), stoppingToken);
}
_logger.LogInformation("InactiveUserNotifierService stopped.");
}
}private async Task RunScopedAsync(Func<IServiceProvider, Task> action)
{
using var scope = _scopeFactory.CreateScope();
await action(scope.ServiceProvider);
}await RunScopedAsync(async services =>
{
var userRepository = services.GetRequiredService<IUserRepository>();
// منطق کار با کاربران غیرفعال
});