Why is logging setup in CreateHostBuilder and not in ConfigureServices?

Viewed 4444

Context: Simple out-of-the-box blazor 3.1 SERVER SIDE example - adding logging (just trying to get stuff to the debug conolse in VS2019 in components).

I leave ConfigureServices as is, and have found SO examples that logging is setup in program.cs(!) This works:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(
                logging =>
                {
                    logging.ClearProviders();
                    logging.AddConsole();
                })

ect.

In my components, everything is resolved fine with

[Inject] public ILogger<Foo> Logger { get; set; }

But why not in ConfigureServices, where rest of stuff, that should be DI'ed, is setup ???

  1. Is there a "under the hood" DI going on? (a little like what was going on in .Net frameework w/ webapi)?
  2. Can it be moved to ConfigureServices with excact same result (or at all )?
1 Answers

In ASP.NET core 2.x you could partially configure your dependency injection container in Program.cs, and inject the configured classes into Startup.cs. So the ConfigureLogging() method calls ConfigureServices() on the IWebHostBuilder instance, and configures some settings. As these services are configured in the DI container before Startup is instantiated, they can be injected into the Startup constructor:

public Startup(
  IConfiguration configuration, 
  ILogger<Startup> logger) // Inject pre-configured service
{
}

More

But this approach is no longer supported in ASP.NET Core 3.0! The problem is that it requires building the dependency injection container twice.

  1. Is there a "under the hood" DI going on? (a little like what was going on in .Net frameework w/ webapi)?

The ConfigureLogging just call ConfigureServices without building of service provider

public static IWebHostBuilder ConfigureLogging(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, ILoggingBuilder> configureLogging)
{
     return hostBuilder.ConfigureServices((context, collection) => collection.AddLogging(builder => configureLogging(context, builder)));
}
  1. Can it be moved to ConfigureServices with excact same result (or at all )?

yes, you can move it to ConfigureServices and the result will be the same

public void ConfigureServices(IServiceCollection services)
{
    services.AddLogging(builder =>
    {
        builder.ClearProviders();
        builder.AddConsole();
    });
}

So, where to add logging configuration is up to you. Logging is infrastructure and can be added as a configuration of host to Program.cs. Your business classes should be added to DI in Startup.

Related