How to register ILogger for injection in ASP.NET MVC 6

C#LoggingDependency Injectionasp.net Core-Mvc

C# Problem Overview


I have a ASP.NET MVC 6 (beta-4) app.

public void ConfigureServices(IServiceCollection services)
{
    // Logging
    services.AddLogging();

    // ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
    // Add the console logger.
    loggerfactory.AddConsole(minLevel: LogLevel.Warning);

    // ...
}

And I have a controller...

public class HomeController : 
    Controller
{
    ILogger _logger;
    
    public HomeController(ILogger logger) 
    {
        _logger = logger;
    }

    // ...
}

But when I'm not getting the service registered correctly somehow: InvalidOperationException: Unable to resolve service for type 'Microsoft.Framework.Logging.ILogger' while attempting to activate 'HomeController'.. What am I doing wrong with the registering the logger?

C# Solutions


Solution 1 - C#

I assumed that services.AddLogging(); was doing the right thing and registering ILogger. After looking at the source (https://github.com/aspnet/Logging/blob/d874c5726e713d3eb34938f85faf7be61aae0f2a/src/Microsoft.Framework.Logging/LoggingServiceCollectionExtensions.cs) I found that it's actually registering ILogger<>. Changing the signature of ILogger to ILogger<HomeController> makes the above example work.

public class HomeController : 
    Controller
{
    ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger) 
    {
        _logger = logger;
    }

    // ...
}

Thanks to @Steve for setting me on the right track to find this.

Solution 2 - C#

The services.AddLogging(); didn't worked for me, so I added these two statements to ConfigureServices:

services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));

Now the DI container is happy and everything works.

Solution 3 - C#

just add this line to ConfigureServices

services.AddSingleton(Serilog.Log.Logger);

Solution 4 - C#

.NET 5.0 Solution; its worked with normal controller and generic controller too:

public class EnhancedGeneric<T> : BaseApiController
{
    private readonly ILogger _logger;

    public EnhancedGeneric(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger(typeof(T).Name);
    }

    public void OnGet()
    {
        _logger.LogInformation("GET pages called.");
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTravisView Question on Stackoverflow
Solution 1 - C#TravisView Answer on Stackoverflow
Solution 2 - C#rubitoView Answer on Stackoverflow
Solution 3 - C#Ali BesharatiView Answer on Stackoverflow
Solution 4 - C#mRizvandiView Answer on Stackoverflow