在我的 API 中,我使用“AddHostedService”注册了一些服务,这些服务需要注入一些接口,例如:
Program.cs:
builder.Services.AddScoped<IHypervisorRepository, HypervisorRepository>();
builder.Services.AddScoped<IAccountRepository, AccountRepository>();
builder.Services.AddScoped<ICloudStackDbUnitOfWork, CloudStackDbUnitOfWork>();
builder.Services.AddScoped<ICloudStackCoreConnectionFactory, MySqlCloudStackCoreConnectionFactory>();
builder.Services.AddScoped<IJobUtility, JobUtility>();
builder.Services.AddScoped<IVdcUnitOfWork, VdcUnitOfWork>();
builder.Services.AddScoped<IMemoryCache, MemoryCache>();
builder.Services.AddHostedService<CheckDatabaseHealthBackgroundService>();
CheckDatabaseHealthBackgroundService.cs:
public sealed class CheckDatabaseHealthBackgroundService : BackgroundService, IDisposable
{
private readonly IServiceProvider _provider;
private readonly IJobUtility _jobUtility;
private readonly IVdcUnitOfWork _unitOfWork;
private readonly ICloudStackCoreConnectionFactory _connFactory;
private readonly IMemoryCache _cache;
private readonly ILogger<CheckDatabaseHealthBackgroundService> _logger;
public CheckDatabaseHealthBackgroundService(
IServiceProvider provider,
IJobUtility jobUtility,
IVdcUnitOfWork unitOfWork,
ICloudStackCoreConnectionFactory connFactory,
IMemoryCache cache,
ILogger<CheckDatabaseHealthBackgroundService> logger)
{
_provider = provider;
_jobUtility = jobUtility;
_unitOfWork = unitOfWork;
_connFactory = connFactory;
_cache = cache;
_logger = logger;
}
但是在我启动 API 后,会抛出以下异常:
System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: CloudStackData.WebAPI.RefreshDiskTypeBackgroundService': Cannot consume scoped service 'Vdc.Libs.Data.IVdcUnitOfWork' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.
---> System.InvalidOperationException: Cannot consume scoped service 'Vdc.Libs.Data.IVdcUnitOfWork' from singleton 'Microsoft.Extensions.Hosting.IHostedService'
读完这个错误后,我得出结论,我应该将“CheckDatabaseHealthBackgroundService”所需的服务添加为单例,而不是限定范围,所以我尝试了:
Program.cs:
builder.Services.AddScoped<IHypervisorRepository, HypervisorRepository>();
builder.Services.AddScoped<IAccountRepository, AccountRepository>();
builder.Services.AddScoped<ICloudStackDbUnitOfWork, CloudStackDbUnitOfWork>();
builder.Services.AddScoped<ICloudStackCoreConnectionFactory, MySqlCloudStackCoreConnectionFactory>();
builder.Services.AddSingleton<IJobUtility, JobUtility>();
builder.Services.AddSingleton<IVdcUnitOfWork, VdcUnitOfWork>();
builder.Services.AddSingleton<IMemoryCache, MemoryCache>();
builder.Services.AddHostedService<CheckDatabaseHealthBackgroundService>();
现在抛出的异常是:
System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: CloudStackData.WebAPI.RefreshDiskTypeBackgroundService': Cannot consume scoped service 'Vdc.Libs.Data.DbContextWrite' from singleton 'Vdc.Libs.Data.IVdcUnitOfWork'.
我开始陷入困境。
VdcUnitOfWork 是我们的另一个库。
VdcUnitOfWork.cs:
public sealed class VdcUnitOfWork : EFDbUnitOfWork<DbContextWrite>, IVdcUnitOfWork, IUnitOfWork, IDisposable, IDbContextWrapper
{
public VdcUnitOfWork(DbContextWrite dbContext)
: base(dbContext)
{
}
}
DbContextWrite 也是我们的另一个库。
DbContextWrite.cs:
public abstract class DbContextWrite : DbContext
{
protected DbContextWrite([NotNull] DbContextOptions options)
: base(options)
{
}
}
事实是,在使用 AddHostedService 添加托管服务后,我无法再运行该 API(我有四个托管服务,但为了简化只放了一个)。
有什么帮助吗?
要在
HostedService
(单例)中使用作用域服务,您需要注入 IServiceScopeFactory
(使用 .NET 8.0
中的主构造函数):
public sealed class CheckDatabaseHealthBackgroundService
(IServiceScopeFactory scopeFactory) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// get scoped services:
using var scope = scopeFactory.CreateScope();
var jobUtility = scope.ServiceProvider.GetService<IJobUtility>();
// do the same with all other scoped Services
}
}