我有以下界面
internal interface IScopedProcessingService
{
Task DoWork(CancellationToken stoppingToken);
}
和实施
public class ConsumeScopedServiceHostedService : BackgroundService
{
private readonly ILogger<ConsumeScopedServiceHostedService> _logger;
public ConsumeScopedServiceHostedService(IServiceProvider services,
ILogger<ConsumeScopedServiceHostedService> logger)
{
Services = services;
_logger = logger;
}
public IServiceProvider Services { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service running.");
await DoWork(stoppingToken);
}
private async Task DoWork(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is working.");
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWork(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is stopping.");
await Task.CompletedTask;
}
}
此代码来自微软官方文档。后台范围服务
就像在文档中一样,我有ScopedProcessingService
一些更困难的。这是代码:
internal class ScopedProcessingService : IScopedProcessingService
{
private int _executionCount;
private readonly ILogger<ConsumeScopedServiceHostedService> _logger;
private readonly IPushRepository _pushRepository;
private readonly IPushTemplateRepository _pushTemplateRepository;
private readonly ISenderLogRepository _senderLogRepository;
private readonly IDistributionRepository _distributionRepository;
// services
private readonly IPushTemplateService _pushTemplateService;
private readonly ISendPushService _sendPushService;
public ScopedProcessingService(
ILogger<ConsumeScopedServiceHostedService> logger,
IPushTemplateService pushTemplateService, ISendPushService sendPushService,
IPushRepository pushRepository,
ISenderLogRepository senderLogRepository, IDistributionRepository distributionRepository,
IPushTemplateRepository pushTemplateRepository)
{
_logger = logger;
_pushTemplateService = pushTemplateService;
_sendPushService = sendPushService;
_pushRepository = pushRepository;
_senderLogRepository = senderLogRepository;
_distributionRepository = distributionRepository;
_pushTemplateRepository = pushTemplateRepository;
}
public async Task DoWork(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_executionCount = _senderLogRepository.SenderLogs.Count();
var logMessage = new StringBuilder();
logMessage.AppendLine($"Начинаю рассылку № {_executionCount}.");
// get all templates. THIS CALL IS A SOURCE OF PROBLEMS
var templates = _pushTemplateRepository.PushTemplates.Where(x => x.isActive)
.Include(x => x.Messages)
.ThenInclude(x => x.PushLang)
.Include(x => x.Category)
.Include(x => x.AdvertiserPushTemplates)
.ThenInclude(x => x.Advertiser)
.ToList();
}
}
在Startup.cs
类中,我使用以下代码注入它:
services.AddHostedService<ConsumeScopedServiceHostedService>();
services.AddScoped<IScopedProcessingService, ScopedProcessingService>();
这条线的问题var templates = _pushTemplateRepository.PushTemplates.Where(x => x.isActive)
。如果我使用 a 进行一些更改,PushTemplate
此更改将不会对后台任务产生影响。我将处理旧数据。我的意思是,如果我更改 a 的名称PushTemplate
,例如,将 id = 15 从Name_1
to更改Name_2
为我将Name_1
在后台任务中使用的名称。
如何EF
正确注入 Scoped 后台服务?我不使用明确的 EF 上下文。我有存储库层。
public interface IPushTemplateRepository
{
IQueryable<PushTemplate> PushTemplates { get; }
void Save(PushTemplate pushTemplate);
void Delete(int templateid);
}
和实施
public class PushTemplateRepository : IPushTemplateRepository
{
private readonly ApplicationDbContext _applicationContext;
public PushTemplateRepository(ApplicationDbContext applicationContext)
{
_applicationContext = applicationContext;
}
public IQueryable<PushTemplate> PushTemplates => _applicationContext.PushTemplates;
public void Save(PushTemplate pushTemplate)
{
// ...
}
public void Delete(int templateid)
{
// ...
}
}