Unable to resolve ILogger from Microsoft.Extensions.Logging

reggaemahn picture reggaemahn · Oct 22, 2018 · Viewed 38.3k times · Source

I've configured my console application's Main like so

var services = new ServiceCollection()
                .AddLogging(logging => logging.AddConsole())
                .BuildServiceProvider();

And then I try to use it in another class like so

    private readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public void MyFunc()
    {
        _logger.Log(LogLevel.Error, "My Message");
    }

System.InvalidOperationException: 'Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger'

I've tried the solutions here but it didn't work for me.

Edit Based on Yaakov's comment below and this Github comment I'm able to resolve it correctly by doing this

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

I would have preferred to have this in the initial BuildServiceProvider but looks like I'm gonna have to repeat this every time I want to use the logger (or create my own ILogger).

Answer

Sam Shiles picture Sam Shiles · Aug 21, 2019

ILogger is no longer registered by default but ILogger<T> is. If you still want to use ILogger you can registered it manually with the following (Startup.cs):

    public void ConfigureServices(IServiceCollection services)
    {
        var serviceProvider = services.BuildServiceProvider();
        var logger = serviceProvider.GetService<ILogger<AnyClass>>();
        services.AddSingleton(typeof(ILogger), logger);
        ...
     }

Where AnyClass can be something generic, such as:

     public class ApplicationLogs
     {
     }

So:

        public void ConfigureServices(IServiceCollection services)
        {
            var serviceProvider = services.BuildServiceProvider();
            var logger = serviceProvider.GetService<ILogger<ApplicationLog>>();
            services.AddSingleton(typeof(ILogger), logger);
            ...
         }

ILogger will now resolve via constructor injection