【问题标题】:How to init, inject and use a Logger in a abp.io Console application如何在 abp.io 控制台应用程序中初始化、注入和使用 Logger
【发布时间】:2021-11-08 14:56:18
【问题描述】:

Console Application Startup Template 开始,我想注册、配置和使用Logger(Microsoft、Serilog 或任何其他;我不介意)和FluentScheduler

这是我从初始模板更改的代码,但它不起作用:Logger 始终设置为 NullLogger :-(

    class Program {

        static async Task Main(string[] args) {
            await CreateHostBuilder(args).RunConsoleAsync();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(build => {
                    build.AddJsonFile("appsettings.secrets.json", optional: true);
                })
                .ConfigureServices((hostContext, services) => {
                    // === TRY CFG LOGGER HERE - start
                    services.AddLogging(cfg => {
                        var configuration = new ConfigurationBuilder()
                            .SetBasePath(Directory.GetCurrentDirectory())
                            .AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
                            .Build();
                        cfg.AddConfiguration(configuration);
                    });
                    // === TRY CFG LOGGER HERE - end

                    services.AddHostedService<ConsoleTestAppHostedService>();
                });
    }

    public class ConsoleTestAppHostedService : IHostedService {
        // ... see https://docs.abp.io/en/abp/latest/Startup-Templates/Console
    }

    public abstract class AbstractAbpJob : IJob, ITransientDependency {

        public ILogger Logger { get; set; }    // <=== it not injected

        public AbstractAbpJob() {
            Logger = NullLogger<AbstractAbpJob>.Instance;
        }

        public abstract void Execute();
    }

请帮忙。

【问题讨论】:

  • 尝试过构造函数注入吗?
  • 另外,您需要为 ILogger 定义一个目录。在您的情况下,应该是ILogger&lt;AbstractAbpJob&gt;

标签: logging dependency-injection console-application abp


【解决方案1】:

添加代码。

    ...
    application.Services.AddSingleton<ILoggerFactory>(
      (Func<IServiceProvider, ILoggerFactory>)(services => new SerilogLoggerFactory(Log.Logger)));

【讨论】:

    【解决方案2】:

    感谢您的所有留言,感谢@ma-huwei 的建议。我终于找到了一个有效的代码:

        class Program {
            static async Task Main(string[] args) {
                // Its important that logging is default initialized as early
                // as possible, so that errors that might prevent your app from
                // starting are logged
                Log.Logger = new LoggerConfiguration()
                    .WriteTo.Console()
                    // CreateBootstrapLogger() sets up Serilog so that the initial
                    // logger configuration (which writes only to Console),
                    // can be swapped out later in the initialization process,
                    // once the hosting infrastructure is available.
                    .CreateBootstrapLogger();
                Log.Information($"Starting up...");
    
                try {
                    await CreateHostBuilder(args).RunConsoleAsync();
                }
                finally {
                    Log.Information("=== Program terminated ===");
                    Log.CloseAndFlush();
                }
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration((hostingCtx, build) => {
                        build.AddJsonFile("appsettings.json", optional: true);
                        build.AddJsonFile(path: "appsettings.secrets.json", optional: true, reloadOnChange: true);
                    })
                    .ConfigureServices(services => {
                        // this is the (let's say) "new" 'console main'
                        services.AddHostedService<ProgramAppHostedService>();
                    })
                    .UseSerilog((context, loggerConfig) => {
                        loggerConfig.ReadFrom.Configuration(context.Configuration);
                    });
        }
    

    这是被调用的ProgramAppHostedService

       /// <summary>
        ///     This is the new '.NET main' activated by Program.Main.
        ///     The advantage here is that DI, logging, etc. are now available
        /// </summary>
        public class ProgramAppHostedService : IHostedService {
    
            private readonly IHostApplicationLifetime _appLifetime; 
            private readonly IConfiguration _configuration;
            private readonly ILogger<ProgramAppHostedService> _logger;
    
            private byte[] _appsettingsHash = new byte[20];
    
            private static object _initLock = new object();
    
            public ProgramAppHostedService(
                IHostApplicationLifetime appLifetime, 
                IConfiguration configuration, 
                ILogger<ProgramAppHostedService> logger) {
                _appLifetime = appLifetime;
                _configuration = configuration;
                _logger = logger;
            }
    
            /// <summary>
            ///     Gracefully shutdown the application
            /// </summary>
            public Task StopAsync(CancellationToken cancellationToken) {
                _logger.LogInformation("Application host stopped");
                return Task.CompletedTask;
            }
    
            /// <summary>
            ///     This the Apb.io main. It is automatically invoked by the .NET framework IHost system.
            /// </summary>
            public async Task StartAsync(CancellationToken cancellationToken) {
                try {
                    using (var abpApplication = await AbpApplicationFactory.CreateAsync<ProgramAppModule>(options => {
                        options.Services.ReplaceConfiguration(_configuration);
                        options.UseAutofac();   //Autofac integration
                        // this is important to ensure correct logger injectio cfg
                        options.Services.AddLogging(c => c.AddSerilog());
                    })) {
                        _logger.LogInformation("Application initialize...");
                        await abpApplication.InitializeAsync();
                        _logger.LogInformation("Application initialized");
    
                        try {
                            // Resolve a service and use it
                            var helloWorldService = abpApplication.ServiceProvider.GetService<HelloWorldService>();
                            await helloWorldService.SayHello();
                        }
                        finally {
                            await abpApplication.ShutdownAsync();
                        }
                    }
                }
                finally {
                    _appLifetime.StopApplication();
                }
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-05
      • 2015-11-01
      • 2012-03-29
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多