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
相关产品推荐
相关产品推荐

