首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法构造某些服务(验证服务描述符的...IHostedService时出错

无法构造某些服务(验证服务描述符的...IHostedService时出错
EN

Stack Overflow用户
提问于 2020-06-22 23:52:58
回答 1查看 1.4K关注 0票数 0

我一直在阅读我能找到的关于依赖注入的东西,但我似乎找不到这里我错了什么。我有一个后台服务,可以设置为每天运行一次,运行良好。后台服务将每天运行,并检查列中是否有任何行的日期早于今天。当我试图将它与一个DB上下文组合在一起,以便它可以做我想做的事情时,问题就出现了。下面是我检索表格数据的尝试。

代码语言:javascript
运行
复制
public class GetSR : IGetSR
    {
        private readonly Template.Data.ServiceContext _context;

        public GetSR(Template.Data.ServiceContext context)
        {
            _context = context;
        }

        public IList<ServiceSummary> Service_Request_Informations { get; set; }

        public async Task GetRequests()
        {
            IQueryable<ServiceSummary> listIQ = from s in _context.Summary select s;
            listIQ = listIQ.Where(s => s.FollowUpDate < DateTime.Now);
            Service_Request_Informations = await listIQ.AsNoTracking().ToListAsync();
        }
    }

这是一个界面:

代码语言:javascript
运行
复制
public interface IGetSR
{
    Task GetRequests();
}

这是我的后台服务:

代码语言:javascript
运行
复制
public class ScheduledUpdate : BackgroundService
{
    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        ...
    }

    public ScheduledUpdate(IGetSR GetSR)
    {
        _Requests = GetSR;
    }
    public readonly IGetSR _Requests;
}

Startup.cs

代码语言:javascript
运行
复制
...
public void ConfigureServices(IServiceCollection services)
{
     services.AddRazorPages();

     services.AddTransient<IGetSR, GetSR>();
...
}
...

我的代码将不再构建。如果我正确理解DI,我应该不需要像GetSR那样将IGetSR的作用域设置为BackgroundService,但它却说它不能被作用域。我在这里做错了什么?

解决:多亏了Compufreak。我需要做一些调整才能为我工作

代码语言:javascript
运行
复制
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
    using var scope = _ServiceProvider.CreateScope();
    var requests = scope.ServiceProvider.GetRequiredService<IGetSR>();

    var DailyTime = "15:00:00";
    var timeParts = DailyTime.Split(new char[1] { ':' });

    while (!stoppingToken.IsCancellationRequested)
    {
        var dateNow = DateTime.Now;
        var date = new DateTime(dateNow.Year, dateNow.Month, dateNow.Day, int.Parse(timeParts[0]), int.Parse(timeParts[1]), int.Parse(timeParts[2]));
        TimeSpan ts;

        if (date > dateNow)
        {
            ts = date - dateNow;
        }
        else
        {
            date = date.AddDays(1);
            ts = date - dateNow;
        }

        await Task.Delay(ts, stoppingToken);
        await requests.GetRequests();
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-23 01:06:51

后台服务的作用域不能作为.NET核心应用程序中的作用域-Web应用程序通常由webrequest初始化。根据设计,后台服务独立于works请求工作。

但是您可以在BackgroundService中注入ServiceProvider并创建自己的作用域:

代码语言:javascript
运行
复制
public class ScheduledUpdate : BackgroundService
{
    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using ( var scope = this.services.CreateScope() )
        {
            var requests = scope.ServiceProvider.GetRequiredService<IGetSR>();
        }
    }

    public ScheduledUpdate(IServiceProvider serviceProvider)
    {
        _ServiceProvider = serviceProvider;
    }

    private readonly IServiceProvider _ServiceProvider;
}

DbContext被设计为限定作用域,因此您不应将其更改为不限定作用域。对于像干净的数据库连接的处置/池化这样的东西,它是必需的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62518468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档