如何在abp.io控制台应用中初始化、注入Logger并集成FluentScheduler
ABP控制台模板Logger注入失败问题修复方案
核心问题原因
- 未接入ABP框架的初始化流程:你直接使用.NET原生HostBuilder搭建项目,没有走ABP的模块加载与DI容器初始化逻辑,ABP特有的属性注入能力(即直接声明
public ILogger Logger { get; set; }自动注入)仅对ABP容器解析的服务生效,原生Host创建的服务不会触发该逻辑。 - FluentScheduler默认不对接第三方DI容器:FluentScheduler默认自行实例化Job对象,不会从你的DI容器中获取Job实例,就算你注册了Job,框架也拿不到注入的Logger。
- 日志配置冗余冲突:你在
ConfigureServices中重复构建配置对象注册日志,和ABP内置的日志注册逻辑冲突,导致日志实例解析异常。
具体修改步骤
1. 改用ABP标准控制台初始化流程
修改Program.cs代码,使用ABP官方提供的控制台应用启动方式,自动集成ABP的DI、日志等基础能力:
class Program { static async Task Main(string[] args) { // 提前配置Serilog(也可以用微软原生日志,这里用Serilog举例) Log.Logger = new LoggerConfiguration() #if DEBUG .MinimumLevel.Debug() #else .MinimumLevel.Information() #endif .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() .WriteTo.Async(c => c.Console()) .CreateLogger(); try { await AbpApplicationFactory.CreateAsync<ConsoleTestAppModule>(options => { options.UseAutofac(); // ABP默认用Autofac实现高级DI能力 options.Services.AddLogging(c => c.AddSerilog()); options.Services.AddHostedService<ConsoleTestAppHostedService>(); }).RunAsync(); } catch (Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly!"); } finally { Log.CloseAndFlush(); } } } // 新增ABP模块类,用于配置服务 public class ConsoleTestAppModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { // 你可以在这里注册其他自定义服务 var configuration = context.Services.GetConfiguration(); // 加载appsettings.secrets.json的逻辑ABP已经默认实现,不用额外加 } }
2. 自定义FluentScheduler Job工厂,对接ABP DI容器
修改FluentScheduler的配置,让它从ABP的IServiceProvider中解析Job实例,这样属性注入才会生效:
// 自定义Job工厂 public class AbpJobFactory : IJobFactory { private readonly IServiceProvider _serviceProvider; public AbpJobFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IJob GetJobInstance<T>() where T : IJob { return _serviceProvider.GetRequiredService<T>(); } } // 在ConsoleTestAppHostedService中配置FluentScheduler public class ConsoleTestAppHostedService : IHostedService { private readonly IServiceProvider _serviceProvider; public ConsoleTestAppHostedService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public Task StartAsync(CancellationToken cancellationToken) { // 替换默认Job工厂 JobManager.JobFactory = new AbpJobFactory(_serviceProvider); // 注册你的Job,比如每分钟执行一次 JobManager.AddJob<MyCustomJob>(s => s.ToRunEvery(1).Minutes()); JobManager.Start(); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { JobManager.Stop(); return Task.CompletedTask; } }
3. 简化抽象Job类
ABP的属性注入会自动覆盖你构造函数赋值的NullLogger,不用做额外修改:
public abstract class AbstractAbpJob : IJob, ITransientDependency { // 只要是从ABP容器解析的Job,该属性会自动注入 public ILogger Logger { get; set; } public AbstractAbpJob() { // 兜底赋值,不影响注入逻辑 Logger = NullLogger<AbstractAbpJob>.Instance; } public abstract void Execute(); } // 你的具体Job实现 public class MyCustomJob : AbstractAbpJob { public override void Execute() { Logger.LogInformation("Job执行成功"); } }
内容的提问来源于stack exchange,提问作者Gianpiero
相关产品推荐
相关产品推荐

