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

C#实例化Error类时如何通过依赖注入使用Serilog的ILogger

解决C#中Error类依赖注入ILogger的问题

1. 修正Error类的构造函数

首先确保Error类通过构造函数接收ILogger,这是依赖注入的基础:

public class Error
{
    private readonly ILogger<Error> _logger;

    // 构造函数注入ILogger(推荐用泛型版本,便于日志分类)
    public Error(ILogger<Error> logger)
    {
        _logger = logger;
    }

    // 示例:日志记录方法
    public void LogJobError(string jobId, string message)
    {
        _logger.Error("作业 {JobId} 执行出错: {Message}", jobId, message);
    }

    // 存储错误信息的属性
    public string JobId { get; set; }
    public string ErrorMessage { get; set; }
    // 其他所需属性...
}

2. 将Error类注册到依赖注入容器

在项目的服务配置文件(如.NET 6+的Program.cs)中,把Error类注册到DI容器,根据你的业务需求选择生命周期:

var builder = WebApplication.CreateBuilder(args);

// 确保Serilog已配置(你应该已经完成这一步)
builder.Host.UseSerilog();

// 注册Error类:
// - AddTransient: 每次获取都创建新实例(适合无状态的类)
// - AddScoped: 每个请求/作用域内一个实例(Web应用常用)
// - AddSingleton: 全局唯一实例
builder.Services.AddTransient<Error>();

// 其他服务注册(如Quartz、控制器等)...

var app = builder.Build();
// 后续配置...

3. 在Quartz作业中使用Error类(避免手动new)

Quartz默认会自行实例化Job对象,因此需要配置它使用DI容器的Job工厂,才能支持构造函数注入:

配置Quartz使用DI Job工厂

在Program.cs的Quartz注册代码中添加以下配置:

builder.Services.AddQuartz(q =>
{
    // 注册你的作业类
    q.AddJob<YourJobClass>(opts => opts.WithIdentity("YourJob"));
    // 配置触发器(根据你的需求调整)
    q.AddTrigger(opts => opts
        .ForJob("YourJob")
        .WithIdentity("YourJobTrigger")
        .WithSimpleSchedule(s => s.WithIntervalInMinutes(5).RepeatForever()));

    // 关键:让Quartz使用DI容器创建Job实例
    q.UseMicrosoftDependencyInjectionJobFactory();
});

// 注册Quartz托管服务
builder.Services.AddQuartzHostedService(opts => opts.WaitForJobsToComplete = true);

在JobClass中注入Error

现在可以直接在Job的构造函数中注入Error,无需手动new Error():

public class YourJobClass : IJob
{
    private readonly Error _error;

    // 构造函数注入Error
    public YourJobClass(Error error)
    {
        _error = error;
    }

    public Task Execute(IJobExecutionContext context)
    {
        // 使用Error实例存储信息并记录日志
        _error.JobId = context.JobDetail.Key.Name;
        _error.ErrorMessage = "作业执行过程中出现警告";
        _error.LogJobError(_error.JobId, _error.ErrorMessage);

        // 将Error传递给UI的逻辑(如存入数据库、发送信号等)...

        return Task.CompletedTask;
    }
}

特殊场景:必须手动创建Error实例(不推荐)

如果因为某些限制必须手动创建Error,可以在JobClass中注入IServiceProvider,通过作用域获取实例:

public class YourJobClass : IJob
{
    private readonly IServiceProvider _serviceProvider;

    public YourJobClass(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public Task Execute(IJobExecutionContext context)
    {
        // 创建作用域(确保服务生命周期正确)
        using var scope = _serviceProvider.CreateScope();
        var error = scope.ServiceProvider.GetRequiredService<Error>();

        // 使用error实例...

        return Task.CompletedTask;
    }
}

核心要点

  • 永远不要通过new Error()手动实例化需要依赖注入的类,否则DI容器无法自动注入ILogger
  • 确保所有需要DI的类都通过构造函数声明依赖,并注册到DI容器
  • Quartz作业必须配置UseMicrosoftDependencyInjectionJobFactory才能支持构造函数注入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:27:23