Как выполнить ведение журнала в методе ConfigureServices файла Startup.cs в ASP.NET Core 5.0

Внедрение конструктора логгера в Startupработает в более ранних версиях ASP.NET Core, поскольку для веб-узла создается отдельный контейнер DI. На данный момент для Generic Host создан только один контейнер, см. о Объявлениекритических изменениях .

Startup.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
}

Вопрос. Как мне получить доступ к Регистратору в методе ConfigureServices файла Startup.cs, чтобы передать его другим настраиваемым методам расширения, которые добавляют настраиваемые службы в контейнер?

2 ответа

АСП.НЕТ 5.0

Я использовал функцию активации класса Control Startup , представленную в .NET 5.0 -

Чтобы процитировать документацию MSDN -

Добавлена ​​дополнительная перегрузка UseStartup , которая позволяет приложению предоставлять фабричный метод для управления активацией класса Startup. Управление активацией класса Startup полезно для передачи дополнительных параметров в 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();
Другие вопросы по тегам