在我的 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:验证服务描述符“ServiceType:Microsoft.Extensions.Hosting.IHostedService 生命周期时出错:单例实现类型:CloudStackData.WebAPI.RefreshDiskTypeBackgroundService”:无法使用单例“Microsoft”中的作用域服务“Vdc.Libs.Data.IVdcUnitOfWork” .Extensions.Hosting.IHostedService'.
System.InvalidOperationException:无法使用单例“Microsoft.Extensions.Hosting.IHostedService”中的范围服务“Vdc.Libs.Data.IVdcUnitOfWork”
读完这个错误后,我得出结论,我应该将
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:验证服务描述符“ServiceType:Microsoft.Extensions.Hosting.IHostedService 生命周期时出错:单例实现类型:CloudStackData.WebAPI.RefreshDiskTypeBackgroundService”:无法使用单例“Vdc”中的作用域服务“Vdc.Libs.Data.DbContextWrite” .Libs.Data.IVdcUnitOfWork'.
我开始陷入困境。
VdcUnitOfWork
是我们创建的自定义类:
public sealed class VdcUnitOfWork : EFDbUnitOfWork<DbContextWrite>, IVdcUnitOfWork, IUnitOfWork, IDisposable, IDbContextWrapper
{
public VdcUnitOfWork(DbContextWrite dbContext)
: base(dbContext)
{
}
}
并且
DbContextWrite
是另一个自定义类:
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>();
var unitOfWork = scope.ServiceProvider.GetService<IVdcUnitOfWork>();
var memoryCache = scope.ServiceProvider.GetService<IMemoryCache>();
// Use services here
}
}