簡體   English   中英

ASP.NET Core 5.0中Startup.cs的ConfigureServices方法如何進行日志記錄

[英]How to perform logging in ConfigureServices method of Startup.cs in ASP.NET Core 5.0

在 ASP.NET Core 的早期版本中,構造函數將記錄器注入到Startup中是可行的,因為為 Web 主機創建了一個單獨的 DI 容器。 截至目前,僅為通用主機創建了一個容器,請參閱重大更改公告

啟動.cs

public class Startup
{
    /// <summary> The configuration. </summary>
    public IConfiguration Configuration { get; }
    
    /// <summary> The web host environment. </summary>
    public IWebHostEnvironment WebHostEnvironment { get; }

    public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
    {
        Configuration = configuration;
        WebHostEnvironment = webHostEnvironment;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddServices(Configuration);    // This is a custom method, that adds multiple services to the container.
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger) =>
    app.UseComponents(env, Configuration, logger);
}

現在根據MSDN ,我修改了我的 Startup.cs 如下:

public class Startup
{
    /// <summary> The configuration. </summary>
    public IConfiguration Configuration { get; }
    
    public ILogger<Startup> Logger { get; set; }

    /// <summary> The web host environment. </summary>
    public IWebHostEnvironment WebHostEnvironment { get; }

    public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
    {
        Configuration = configuration;
        WebHostEnvironment = webHostEnvironment;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton((container) =>
        {
            var logger = container.GetRequiredService<ILogger<MyService>>();
            return new Startup(Configuration, WebHostEnvironment) { Logger = logger };
        });    // I know this is incorrect, but that my question- how do I correctly access logger in here?
        services.AddServices(Configuration, Logger);    // Logger => null
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger) =>
    app.UseComponents(env, Configuration, logger);
}

StartupExtension.ConfigureServices.cs

public static partial class StartupExtension
{
    #region Internal Method
    /// <summary> Adds all the services required by the DemoUsageApp. </summary>
    /// <param name="services">The services, <see cref="IServiceCollection"/>.</param>
    /// <param name="configuration">The configuration, <see cref="IConfiguration"/>.</param>
    /// <param name="logger">The logger, <see cref="ILogger{Startup}"/>.</param>
    /// <returns></returns>
    internal static IServiceCollection AddServices(this IServiceCollection services, IConfiguration configuration, ILogger logger)
    {
        services.AddDotNetCoreServices(configuration, logger);
        services.AddCrossCuttingServices(configuration, logger);

        return services;
    }
    #endregion Internal Method

    #region Private Methods
    /// <summary> Adds .NET Core services. </summary>
    /// <param name="services">The services, <see cref="IServiceCollection"/>.</param>
    /// <param name="configuration">The configuration, <see cref="IConfiguration"/>.</param>
    /// <param name="logger">The logger, <see cref="ILogger{Startup}"/>.</param>
    /// <returns></returns>
    private static IServiceCollection AddDotNetCoreServices(this IServiceCollection services, IConfiguration configuration, ILogger logger)
    {
        logger.LogInformation("----  Adding .NET Core components  ----");

        services.AddMvc();
        services.AddControllers();

        logger.LogInformation("----  Successfully added .NET Core components  ----");

        return services;
    }

    /// <summary> Adds Cross-Cutting services. </summary>
    /// <param name="services">The services, <see cref="IServiceCollection"/>.</param>
    /// <param name="configuration">The configuration, <see cref="IConfiguration"/>.</param>
    /// <param name="logger">The logger, <see cref="ILogger{Startup}"/>.</param>
    /// <returns></returns>
    private static IServiceCollection AddCrossCuttingServices(this IServiceCollection services, IConfiguration configuration, ILogger logger)
    {
        logger.LogInformation("----  Adding Cross-Cutting components  ----");

        services.AddSql(configuration, logger);    //This is a extension methods, that adds Sql services (which are also completely custom) to the application.

        logger.LogInformation("----  Successfully added Cross-Cutting components  ----");

        return services;
    }
    #endregion Private Methods
}

問題 -如何在 Startup.cs 的 ConfigureServices 方法中訪問 Logger,以便我可以將其傳遞給將自定義服務添加到容器的其他自定義擴展方法?

注意:為 Microsoft 和 Serilog Logger(可選)請求的解決方案。

更新 1:正如 @MathewBeck 在他的第二條評論中指出的那樣,我已經有了Program.cs的以下結構:

public class Program
{
    #region Public Methods
    /// <summary> Main method, the entry-point of the application. </summary>
    /// <param name="args">The args <see cref="string[]"/></param>
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        var logger = host.Services.GetRequiredService<ILogger<Program>>();
        logger.LogInformation("Host created.");

        host.Run();
    }

    /// <summary> Creates the host builder. </summary>
    /// <param name="args">The args <see cref="string[]"/></param>
    /// <returns></returns>
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            //.ConfigureLogging(loggingBuilder =>
            //{
            //    loggingBuilder.ClearProviders();
            //    loggingBuilder.AddConsole();
            //    loggingBuilder.AddDebug();
            //    loggingBuilder.AddEventLog();
            //    loggingBuilder.AddEventSourceLogger();
            //})
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseConfiguration(GetConfiguration());
            });
    #endregion Public Methods

    #region Private Methods
    /// <summary> Gets the configuration. </summary>
    /// <returns></returns>
    private static IConfiguration GetConfiguration()
    {
        var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", true, true)
            .AddJsonFile($"appsettings.{env}.json", true, true);

        return builder.Build();
    }
    #endregion Private Methods
} 

ASP.NET 5.0

我使用了 .NET 5.0 中引入的Control Startup class 激活功能 -

引用 MSDN 文檔 -

添加了一個額外的UseStartup重載,讓應用程序提供一個工廠方法來控制 Startup class 激活。 Controlling Startup class 激活對於將附加參數傳遞給與主機一起初始化的 Startup 很有用

public class Program
{
    public static async Task Main(String[] args)
    {
        var loggerFactory = LoggerFactory
            .Create(builder =>
            {
                builder.ClearProviders();
                builder.AddConsole();
            });
        var logger = loggerFactory.CreateLogger<Program>();
        var host = Host.CreateDefaultBuilder()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup(context => new Startup(ILogger<Program> logger, /*based on the ctor of startup one can pass the required arguments here*/)
            })
            .Build();

        await host.RunAsync();
    }
}

如果您使用 NLog,登錄 startup.cs 的最簡單方法是添加私有屬性。

private readonly NLog.ILogger _log;

然后在你的構造函數中使用

_log = NLog.LogManager.GetCurrentClassLogger();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM