【问题标题】:how to solve Cannot consume scoped service如何解决无法使用范围服务
【发布时间】: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


【解决方案1】:

试试

services.AddSingleton<IScheduleService, ScheduleService>();

【讨论】:

  • 这根本解决不了问题。 即使在单例中也需要使用作用域服务,例如使用 DbContexts
  • 虽然此代码可能提供问题的解决方案,但强烈建议您提供有关此代码为何和/或如何回答问题的附加上下文。从长远来看,只有代码的答案通常会变得毫无用处,因为未来遇到类似问题的观众无法理解解决方案背后的原因。
猜你喜欢
  • 1970-01-01
  • 2019-06-04
  • 2018-09-27
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 2019-07-02
  • 1970-01-01
相关资源
最近更新 更多