Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ILogger and DependencyInjection in ASP.NET Core 2+

I notice there is no explicit ILogger registration in ConfigureServices in Startup.cs.

First question: how does ILogger get injected into e.g. controllers.

Second question: how do I configure ILogger to get injected into middleware?

like image 509
pomeroy Avatar asked Sep 01 '18 03:09

pomeroy


Video Answer


1 Answers

Logging is added as part of the HostBuilder.Build process

private void CreateServiceProvider()
{
    var services = new ServiceCollection();
    services.AddSingleton(_hostingEnvironment);
    services.AddSingleton(_hostBuilderContext);
    services.AddSingleton(_appConfiguration);
    services.AddSingleton<IApplicationLifetime, ApplicationLifetime>();
    services.AddSingleton<IHostLifetime, ConsoleLifetime>();
    services.AddSingleton<IHost, Host>();
    services.AddOptions();
    services.AddLogging();//<--HERE

    //...

WebHostBuilder.BuildCommonServices

    private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
    {

        //... code removed for brevity

        var services = new ServiceCollection();
        services.AddSingleton(_options);
        services.AddSingleton<IHostingEnvironment>(_hostingEnvironment);
        services.AddSingleton<Extensions.Hosting.IHostingEnvironment>(_hostingEnvironment);
        services.AddSingleton(_context);

        var builder = new ConfigurationBuilder()
            .SetBasePath(_hostingEnvironment.ContentRootPath)
            .AddConfiguration(_config);

        _configureAppConfigurationBuilder?.Invoke(_context, builder);

        var configuration = builder.Build();
        services.AddSingleton<IConfiguration>(configuration);
        _context.Configuration = configuration;

        var listener = new DiagnosticListener("Microsoft.AspNetCore");
        services.AddSingleton<DiagnosticListener>(listener);
        services.AddSingleton<DiagnosticSource>(listener);

        services.AddTransient<IApplicationBuilderFactory, ApplicationBuilderFactory>();
        services.AddTransient<IHttpContextFactory, HttpContextFactory>();
        services.AddScoped<IMiddlewareFactory, MiddlewareFactory>();
        services.AddOptions();
        services.AddLogging();

To get ILogger injected into a controller just include it in the constructor as a dependency

private readonly ILogger logger;

public MyController(ILogger<MyController> logger) {
    this.logger = logger;
}

//...

and the framework will inject it into the controller when it is being activated.

Reference Dependency injection into controllers in ASP.NET Core

The same can be done for Middleware vai constructor injection just like with the controller,

or directly into the Invoke method for per-request dependencies

public Task Invoke(HttpContext context, ILogger<MyMiddleware> logger) {
    //...
}

like any other injected service

Reference ASP.NET Core Middleware

like image 96
Nkosi Avatar answered Oct 05 '22 23:10

Nkosi