Как настроить ConsoleLogger в консольном приложении?

Я пытаюсь создать консольное приложение, используя .NET CORE 3.1, и у меня возникла проблема с внедрением консольного регистратора.

Похоже, что в последних версиях способ внедрения ведения журнала значительно изменился, и ни один из различных вариантов обучающих руководств, похоже, не соответствует тому, что я пытаюсь сделать.

У меня есть интерфейс:

public interface IMyDoer
{
    void DoSomething();
}

И класс, в который я хочу внедрить ILogger:

public class MyDoer : IMyDoer
{
    private readonly ILogger logger;
    public MyDoer(ILogger logger)
    {
        this.logger = logger;
    }

    public void DoSomething()
    {
        this.logger.Log(LogLevel.Information, "Doing something");
    } 
}

Затем у меня есть мой Main(), где я пытаюсь настроить контейнер DI для создания объекта Doer, настраивая ILogger для входа в консоль.

public class Program
{
    public static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        ConfigureServices(serviceCollection);

        var serviceProvider serviceCollection.BuildServiceProvider();

        var myDoer = serviceProvider.GetService<IMyDoer>();

        myDoer.DoSomething();
    }

    private static void ConfigureServices(ServiceCollection serviceCollection)
    {
        serviceCollection.AddLogging(configure => {
            configure.AddConsole();
        });

        serviceCollection.AddSingleton<IMyDoer, MyDoer>();
    }
}

В качестве альтернативы я пробовал:

public class Program
{
    static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        ConfigureServices(serviceCollection);

        using (var serviceProvider = serviceCollection.BuildServiceProvider())
        using (var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()))
        {
            var myDoer = serviceProvider.GetService<IMyDoer>();

            myDoer.DoSomething();
        }
    }

    private static void ConfigureServices(ServiceCollection serviceCollection)
    {
        serviceCollection
            .AddSingleton<IMyDoer, MyDoer>();
    }
}

В любом случае я получаю исключение:

System.InvalidOperationException
  HResult=0x80131509
  Message=Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'MyDoer.DoSomething'.
  Source=Microsoft.Extensions.DependencyInjection

Есть идеи, как мне следует это сделать?


person Jeff Dege    schedule 26.12.2019    source источник


Ответы (1)


ILogger не зарегистрирован в контейнере DI ASP.NET Core. Вместо этого используйте ILogger<T>:

public class MyDoer : IMyDoer
{
    private readonly ILogger<MyDoer> logger;

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

    // ...
}

ILogger<T> использует имя типа (YourNamespace.MyDoer) в качестве категория журнала:

Эта категория включена в каждое сообщение журнала, созданное этим экземпляром ILogger.

Чтобы установить собственную категорию журнала и создать реализацию ILogger самостоятельно, используйте ILoggerFactory:

public class MyDoer : IMyDoer
{
    private readonly ILogger logger;

    public MyDoer(ILoggerFactory loggerFactory)
    {
        this.logger = loggerFactory.CreateLogger("YourCategory");
    }

    // ...
}
person Kirk Larkin    schedule 26.12.2019