【问题标题】:System.AggregateException: 'Some services are not able to be constructedSystem.AggregateException: '某些服务无法构建
【发布时间】:2021-12-12 17:51:12
【问题描述】:

我在运行我的应用程序时偶然发现了这个错误。

System.AggregateException:'某些服务无法构造(验证服务描述符时出错'ServiceType:Microsoft.Extensions.Hosting.IHostedService Lifetime:Singleton ImplementationType:testing.CacheUpdater':无法解析服务类型' testing.CacheMonitorOptions'同时尝试激活'testing.CacheUpdater'。

应用说明 我正在制作一个应用程序,我会定期(每 10 秒)使用从数据库中获取的值更新 MemoryCache。

为此,我使用了 3 个类,CacheMonitor(负责更新/覆盖缓存)、StudentsContext(负责从数据库中获取数据)和 CacheUpdater,它是一个调用 Update 方法的后台服务在 CacheMonitor 类中。

我已将它们注入到我的 DI 容器中,如下所示:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMemoryCache();
    services.AddHostedService<CacheUpdater>();
    services.AddDbContext<StudentsContext>(options =>
    {
        options.UseSqlServer(Configuration["Database:ConnectionString"]);
    });

    services.Configure<CacheMonitorOptions>(Configuration.GetSection("CacheUpdater"));

    services.AddTransient<ICacheMonitor, CacheMonitor>();

    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "testing", Version = "v1" });
    });
}

CacheMonitor.cs

public class CacheMonitor : ICacheMonitor
{
    private readonly IMemoryCache _cache;
    private readonly ILogger<CacheMonitor> _logger;
    private readonly StudentContext _databaseContext;

    public CacheMonitor(
        IMemoryCache cache,
        IOptions<CacheMonitor> options,
        StudentContext context,
        ILogger<CacheMonitor> logger)
    {
        this._cache = cache;
        this._databaseContext = context;
        this._logger = logger;
    }

    public void UpdateCache()
    {
       //updates cache
    }
}

CacheUpdater.cs

public class CacheUpdater{
    private readonly ICacheMonitor _cacheMonitor;
    private readonly CacheMonitorOptions _cacheMonitorOptions;
    private readonly ILogger<CacheUpdater> _logger;

    public CacheUpdater(
        ICacheMonitor cacheMonitor,
        CacheMonitorOptions cacheMonitorOptions,
        ILogger<CacheUpdater> logger)
    {
        _cacheMonitor = cacheMonitor;
        _cacheMonitorOptions = cacheMonitorOptions;
        _logger = logger;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation($"trying to update cache");
        _cacheMonitor.UpdateCache();
        Thread.Sleep(_cacheMonitorOptions.Interval);

        return Task.CompletedTask;
    }
}

我知道这与服务的生命周期有关,但我不知道如何解决。

【问题讨论】:

  • 检查任何异常以查看是否填充了 InnerException 或 InnerExceptions 属性非常重要。如果是这样,请在您的问题中包含这些详细信息。它们通常是为 AggregateException 填充的。

标签: asp.net .net dependency-injection


【解决方案1】:

CacheUpdater ctor 改为接受IOptions&lt;CacheMonitorOptions&gt; 而不是选项(对其他代码进行相应更改):

 public CacheUpdater(
    ICacheMonitor cacheMonitor,
    IOptions<CacheMonitorOptions> cacheMonitorOptions,
    ILogger<CacheUpdater> logger
    )
    {
        ...
    }

还可以查看docs

UPD

解决来自 cmets 的问题 - 如果您不想在文档中使用来自 timed background tasks 的模式,您可以按照以下方式做一些事情(未经测试):

public class CacheUpdater
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly CacheMonitorOptions _cacheMonitorOptions;
private readonly ILogger<CacheUpdater> _logger;

public CacheUpdater(
    IServiceScopeFactory scopeFactory,
    CacheMonitorOptions cacheMonitorOptions,
    ILogger<CacheUpdater> logger
    )
    {
        _scopeFactory = scopeFactory;
        _cacheMonitorOptions = cacheMonitorOptions;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while(!stoppingToken.IsCancellationRequested) // !
        {
            _logger.LogInformation($"trying to update cache");
            using (var scope = _serviceScopeFactory.CreateScope())
            {
                 var cacheMonitor = scope.ServiceProvider.GetService<ICacheMonitor>(); 
                cacheMonitor.UpdateCache();
                await Task.Delay(_cacheMonitorOptions.Interval, stoppingToken); // DO NOT USE THREAD SLEEP HERE!
            }
        }
    }
}

【讨论】:

  • 现在我得到另一个错误:System.AggregateException:'无法构造某些服务(验证服务描述符时出错'ServiceType:Microsoft.Extensions.Hosting.IHostedService Lifetime:Singleton ImplementationType:测试.CacheUpdater':
  • 不能使用单例“testing.ICacheMonitor”中的范围服务“testing.Models.StudentsContext”。)(验证服务描述符“ServiceType: testing.ICacheMonitor Lifetime: Singleton ImplementationType: testing.CacheMonitor”时出错: 无法使用单例“testing.ICacheMonitor”中的范围服务“testing.Models.StudentContext”。)”
  • @schweppes0x 这完全是其他错误。简而言之,您需要注入IServiceScopeFactory 而不是StudentContext,在需要上下文时创建并从范围解析上下文,例如here
  • @schweppes0x 查看更新。请注意,我尚未测试代码,因此可能需要进行一些修改。
  • 现在好像可以了,但是定期更新不行。由于某种原因,第一次后后台服务无法正常工作。
猜你喜欢
  • 1970-01-01
  • 2020-11-19
  • 2022-08-20
  • 2021-07-07
  • 2021-03-14
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多