You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Quartz调度作业时出现依赖注入生命周期冲突错误

Quartz作业调度启动报错:单例服务无法消费作用域服务

在项目中使用Quartz进行作业调度时,启动阶段抛出System.AggregateException,提示部分服务无法构造。核心原因是:单例生命周期的SendReminderEmails服务尝试消费作用域生命周期的Clinical.Infrastructure.Emails.IAppointmentEmailSender服务,导致服务描述符验证失败。

相关代码

Program.cs

using CcAcca.ApplicationInsights.ProblemDetails;
using Clinical;
using Clinical.Application;
using Clinical.Application.Sockets;
using Clinical.Domain.TemplateAggregate;
using Clinical.Infrastructure.Scheduling.Reminders.Services;
using Clinical.Infrastructure.Scheduling.Reminders;
using H1.Clinical.Api;
using Hellang.Middleware.ProblemDetails;
using Kernel;
using Kernel.Messaging;
using Kernel.Mongo;
using Kernel.Web;
using Kernel.Web.Authentication;
using MassTransit;
using MassTransit.SignalR;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.FeatureManagement;
using Microsoft.OpenApi.Models;
using Quartz.Impl;
using Quartz.Spi;
using Quartz;
using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEnvironmentVariables();

var jwtSettings = new JwtBearerSettings();
builder.Configuration.Bind(nameof(JwtBearerSettings), jwtSettings);

try
{
    Log.Logger = new LoggerConfiguration()
        .CreateBootstrapLogger();

    builder.Host.UseSerilog((hostingContext, service, loggerConfiguration) => loggerConfiguration
        .WriteTo.ApplicationInsights(service.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces)
        .WriteTo.Console()
        .Filter.ByExcluding(e => e.Exception is TaskCanceledException)
        .ReadFrom.Configuration(hostingContext.Configuration));

    Log.Information("healthONE Clinical应用启动中");

    builder.Services.AddSignalR(o =>
    {
        o.HandshakeTimeout = TimeSpan.FromSeconds(5);
        o.KeepAliveInterval = TimeSpan.FromSeconds(30);
    });
    var section = builder.Configuration.GetSection(nameof(MemorySettings));
    builder.Services.Configure<MemorySettings>(section);

    var memorySettings = new MemorySettings();
    section.Bind(memorySettings);

    builder.Services
        .AddHealthChecks()
        .AddProcessAllocatedMemoryHealthCheck(memorySettings.MaxMemoryInMb);
    builder.Services.AddControllers();
    builder.Services.AddFeatureManagement();

    builder.Services
        .AddApplicationInsightsTelemetry(options => { options.EnablePerformanceCounterCollectionModule = false; })
        .AddProblemDetailTelemetryInitializer()
        .AddEndpointsApiExplorer()
        .AddJwtAuthentication(jwtSettings);

    builder.Services.AddSwaggerGen((Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions c) =>
    {
        c.SwaggerDoc("v1",
            new OpenApiInfo
            {
                Title = "healthONE Clinical API",
                Version = "v1",
                Description = "模块化临床API"
            });
        c.EnableAnnotations();
        c.UseAllOfForInheritance();
        c.SelectSubTypesUsing(baseType =>
        {
            if (baseType == typeof(ITemplateField))
            {
                return new List<Type>()
                {
                    typeof(MultiLineText),
                    typeof(Canvas),
                    typeof(Dropdown),
                    typeof(RadioButtonGroup),
                    typeof(SingleLineText),
                    typeof(CheckboxGroup),
                    typeof(TimePicker),
                    typeof(DatePicker)
                };
            }

            return Enumerable.Empty<Type>();
        });
    });

    builder.Services
        .RegisterKernelDependencies()
        .RegisterWebKernel(builder.Environment)
        .RegisterMongoKernel(builder.Configuration, schemaCreatorLocation: null)
        .RegisterClinical(builder.Configuration)
        .RegisterMessaging(
            builder.Configuration,
            options =>
            {
                options.AddSignalRHub<DiaryHub>();
                options.AddSignalRHub<ConsultationHub>();
                options.AddSignalRHub<ArchiveHub>();
                options.AddConsumersFromNamespaceContaining(typeof(ClinicalApplicationModule));
            });

    builder.Services.AddHostedService<QuartzHostedService>();
    builder.Services.AddSingleton<IJobFactory, SingletonJobFactory>();
    builder.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();

    builder.Services.AddSingleton<SendReminderEmails>();
    builder.Services.AddSingleton(new EmailSenderJob(type: typeof(SendReminderEmails), expression: "0/30 0/1 * 1/1 * ? *"));
}
catch (Exception ex)
{
    Log.Fatal(ex, "启动过程中发生未处理异常");
    throw;
}
finally
{
    Log.Debug("关闭完成");
    Log.CloseAndFlush();
}

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();
app.UseProblemDetails();

if (app.Environment.IsDevelopment())
{
    app.UseSerilogRequestLogging();
}

app.UseAuthentication();

app.MapHealthChecks("/healthz");

app.UseAuthorization();

app.MapControllers();
app.MapHub<DiaryHub>("hubs/clinical/diary");
app.MapHub<ConsultationHub>("hubs/clinical/consultation");
app.MapHub<ArchiveHub>("hubs/clinical/archive");

app.Run();

SendReminderEmails.cs

using Quartz;
using Kernel.Users;
using Clinical.Infrastructure.Emails;
using Clinical.Domain.ReminderAggregate;
using Clinical.Infrastructure.Emails.Models;

namespace Clinical.Infrastructure.Scheduling.Reminders.Services
{
    public class SendReminderEmails : IJob
    {
        private readonly IReminderRepository _reminderRepository;
        private readonly IAppointmentEmailSender _appointmentEmailSender;

        public SendReminderEmails(IReminderRepository reminderRepository,
            IAppointmentEmailSender appointmentEmailSender)
        {
            _reminderRepository = reminderRepository;
            _appointmentEmailSender = appointmentEmailSender;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            var reminders = await _reminderRepository.GetAllRemindersofToday();
            foreach (var reminder in reminders)
            {
                //var email = reminder.Email;

                var recipientEmailAddress = Email.TryMake("aliwaheed51@gmail.com"/*patientBooking.Email*/);
                //if (recipientEmailAddress is null)
                //    return BadRequest($"'{patientBooking.Email}' 不是有效的{nameof(Email)}");
                var recipients = new RecipientsModel
                {
                    primaryRecipientEmail = recipientEmailAddress
                };

                await _appointmentEmailSender.SendEmail(recipients, "Ali Waheed" /*当前用户全名*/, "已预约");
            };
        }
    }
}

错误信息

System.AggregateException
  HResult=0x80131500
  消息=部分服务无法构造(验证服务描述符时出错 '服务类型: Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails 生命周期: Singleton 实现类型: Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails': 无法从单例 'Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails' 中使用作用域服务 'Clinical.Infrastructure.Emails.IAppointmentEmailSender'。)
  来源=Microsoft.Extensions.DependencyInjection
  调用栈:
   在 Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options)
   在 Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   在 Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
   在 Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   在 Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   在 Microsoft.Extensions.Hosting.HostBuilder.Build()
   在 Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
   在 Program.<Main>$(String[] args) 位置 E:\Altron\Altron-Backend\src\H1\Clinical.Api\Program.cs:第133行

  此异常最初引发于以下调用栈:
    [外部代码]

内部异常1:
InvalidOperationException: 验证服务描述符时出错 '服务类型: Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails 生命周期: Singleton 实现类型: Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails': 无法从单例 'Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails' 中使用作用域服务 'Clinical.Infrastructure.Emails.IAppointmentEmailSender'。

内部异常2:
InvalidOperationException: 无法从单例 'Clinical.Infrastructure.Scheduling.Reminders.Services.SendReminderEmails' 中使用作用域服务 'Clinical.Infrastructure.Emails.IAppointmentEmailSender'。

内容的提问来源于stack exchange,提问作者Ali Waheed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:07:07