【发布时间】:2020-07-15 18:14:16
【问题描述】:
我在 .net core 3.1 项目中添加了托管服务。但添加托管服务后,我面临以下错误。
不能使用作用域服务
。在此之前我的项目工作正常。我想为我的项目添加后台服务,从数据库中获取数据。
startup.cs
services.AddScoped<IScheduleService, ScheduleService>();
services.AddHostedService<TimedHostedService>();
SMhostedService.cs
internal class TimedHostedService : IHostedService, IDisposable
{
private readonly Microsoft.Extensions.Logging.ILogger _logger;
private Timer _timer;
private IScheduleService _scheduleService;
public TimedHostedService(ILogger<TimedHostedService> logger, IScheduleService scheduleService)
{
_logger = logger;
_scheduleService = scheduleService;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is starting.");
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(10));
return Task.CompletedTask;
}
private void DoWork(object state)
{
_logger.LogInformation("Timed Background Service is working.");
DateTime todaydate = new DateTime();
var getAttendanceStatus = _scheduleService.GetAttendanceStatus(todaydate.Date);
AttendanceStudent obj = new AttendanceStudent();
var ss = _scheduleService.AddAttendanceStudent(obj);
}
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();
}
}
IScheduleService.cs
public interface IScheduleService
{
Task<int> AddAttendanceStudent(AttendanceStudent attendanceStudent);
Task<AttendanceStudent> GetAttendanceStatus(DateTime todaydate);
}
ScheduleService.cs
public class ScheduleService : IScheduleService
{
private readonly IGenericRepository<AttendanceStudent> _studentattendance;
private readonly IGenericRepository<AttendanceStaff> _staffattendance;
private readonly IGenericRepository<SchoolDetails> _schoolDetails;
public ScheduleService(IGenericRepository<AttendanceStudent> studentattendance, IGenericRepository<AttendanceStaff> staffattendance, IGenericRepository<SchoolDetails> schoolDetails)
{
_studentattendance = studentattendance;
_staffattendance = staffattendance;
_schoolDetails = schoolDetails;
}
public async Task<AttendanceStudent> GetAttendanceStatus(DateTime todaydate)
{
var ss = await _studentattendance.FindFirstByAsync(x => x.AttendanceDate == todaydate).ConfigureAwait(false);
return ss;
}
public async Task<int> AddAttendanceStudent(AttendanceStudent attendanceStudent)
{
var studentResult = await _studentattendance.FindFirstByAsync(x => x.StudentId == attendanceStudent.StudentId && x.ClassDetailsId == attendanceStudent.ClassDetailsId && x.AttendanceDate == attendanceStudent.AttendanceDate).ConfigureAwait(false);
if (studentResult == null)
{
await _studentattendance.InsertAsync(attendanceStudent);
return attendanceStudent.AttendanceStudentId;
}
else
{
studentResult.AttendanceType = attendanceStudent.AttendanceType;
await _studentattendance.UpdateAsync(studentResult).ConfigureAwait(false);
return studentResult.StudentId;
}
}
}
【问题讨论】:
-
这篇文章将帮助你理解这个codingblast.com/…
-
这能回答你的问题吗? Cannot consume scoped service from singleton
-
这在后台服务文档的Consuming a scoped service in a background task 部分中进行了解释。在尝试创建作用域实例之前,您需要注入
IServiceProvider并显式创建作用域 -
顺便说一句,“通用”存储库是一种反模式。 DbSet已经是一个存储库,一个 DbContext 是一个工作单元。通过在较高级别的 DbContext 和 DbSet 上添加较低级别的 IGenericRepository,您将一无所获。不过,事情确实变得更难维护和调试 - 例如,这里真正的作用域服务是隐藏在 IGenericRepositories 后面的 DbContexts,而不是 ScheduleService。
-
A DbContext 是一个工作单元 - 它缓存更改并且仅在调用
SaveChanges时保存它们。如果在此之前处理它,它们的更改将被丢弃。这就是为什么它通常是一个范围服务 - 范围还控制着 UoW 的生命
标签: c# .net-core asp.net-core-3.1