Ведение журнала с внедрением зависимостей в консоли .NET без хостинга

Как я могу реализовать ILoggerВнедрение зависимости (например, размещенное приложение) в консольном приложении без размещения? В приведенном ниже коде я хотел бы работать какlogTest1. Это возможно?

Ниже мой appsettings.json - я бы предпочел не определять каждый класс, но это все равно не работает.

{
    "Logging": {
      "LogLevel": {
        "Default": "Information",
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information",
        "ClientTestCli.LogTest":  "Trace"
      }
}

Моя программа консольного приложения:

class Program
{
    static void Main(string[] args)
    {
        HandleArgs(args);

        var serviceProvider = ContainerConfiguration.Configure();

        var logTest1 = new LogTest();
        var logTest2 = new LogTest(serviceProvider.GetService<ILogger<LogTest>>());
        logTest1.LogStuff();
        logTest2.LogStuff();
    }
}

Конфигурация контейнера:

internal static class ContainerConfiguration
{
    public static ServiceProvider Configure()
    {
        return new ServiceCollection()
            .AddLogging(l => l.AddConsole())
            .Configure<LoggerFilterOptions>(c => c.MinLevel = LogLevel.Trace)
            .BuildServiceProvider();
    }
}

Тестовый класс:

internal class LogTest
{
    ILogger<LogTest> logger;
    public LogTest(ILogger<LogTest> logger = null)
    {
        this.logger = logger;
    }

    public void LogStuff()
    {
        logger?.LogCritical("This is a critical log");
    }
}

1 ответ

Решение

Добавить LogTest в коллекцию служб и разрешите ее с помощью поставщика, и поставщик внедрит настроенные регистраторы

Реорганизуйте свой корень композиции

internal static class ContainerConfiguration {
    public static IServiceProvider Configure(Action<IServiceCollection> configuration = null) {
        var services = new ServiceCollection()
            .AddLogging(logging => {
                 logging.ClearProviders();
                 logging.AddConsole();
            })
            .Configure<LoggerFilterOptions>(c => c.MinLevel = LogLevel.Trace);

        configuration?.Invoke(services);

        return services.BuildServiceProvider();
    }
}

И используйте это при запуске

static void Main(string[] args) {
    HandleArgs(args);

    IServiceProvider serviceProvider = ContainerConfiguration.Configure(services => {
        services.AddTransient<LogTest>();
    });

    LogTest logTest = serviceProvider.GetService<LogTest>();

    logTest.LogStuff();
}

Если провайдер используется, он позаботится о построении графа объектов, включая введение необходимых зависимостей.

.Net Fiddle рабочего примера.

Другие вопросы по тегам