.NET Core DI и подклассы

Здесь вы новичок в.NET Core. Я искал другую документацию, ветку или руководство, которое отвечает на мои вопросы, но не могу найти его. Если вы думаете, что да, укажите на это.

Я пытаюсь создать простое консольное приложение.NET 5 с DI и буквально застреваю на структурировании классов с ведением журнала.

  1. Это правильный способ передать регистратор (или любую другую службу) в подкласс с помощью DI в.NET Core? Согласно приведенному ниже коду, в моем конструкторе родительского класса я беру дополнительный ILogger для каждого подкласса, например.ILogger<SubClass>?

    public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)
    
  2. Как мне инициализировать регистратор в моем статическом процессе StaticProc?

    public static async Task<bool> StaticProc()
    

Program.cs:

    с использованием Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    с использованием Microsoft.Extensions.Hosting;
    с помощью Microsoft.Extensions.Logging;
    используя Систему;
    используя System.IO;
    using System.Threading.Tasks;
    
    пространство имен ConsoleApp1
    {
        программа класса
        {
            статическая асинхронная задача Main(строка [] аргументы)
            {
                var builder = новый ConfigurationBuilder();
                BuildConfig(строитель);
    
                var host = Host.CreateDefaultBuilder()
                    .ConfigureServices((контекст, услуги) =>
                    {
                        services.AddTransient();
                        services.AddTransient();
                    }).ConfigureLogging (logBuilder =>
                    {
                        logBuilder.SetMinimumLevel (LogLevel.Trace);
                        logBuilder.AddLog4Net ("log4net.config");
                    }).Build ();
    
                var log = host.Services.GetService().CreateLogger();
    
                log.LogInformation ($ "Приложение запущено");
    
                var svc = ActivatorUtilities.CreateInstance(host.Services);
                ждать svc.Run();
    
                log.LogInformation($"Приложение завершено");
            }
    
            static void BuildConfig(построитель IConfigurationBuilder)
            {
                builder.SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", необязательно: false, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")?? " Разработка "}. Json", необязательно: true).AddEnvironmentVariables();
            }
        }
    }

TestClass.cs:

    с использованием Microsoft.Extensions.Configuration;
    с помощью Microsoft.Extensions.Logging;
    using System.Threading.Tasks;
    
    пространство имен ConsoleApp1
    {
        открытый класс TestClass: ITestClass
        {
            закрытый только для чтения ILogger _log;
            закрытый только для чтения ILogger _subClassLog;
            закрытый только для чтения IConfiguration _config;
    
            общедоступный TestClass(журнал ILogger, ILogger subClassLog, конфигурация IConfiguration)
            {
                _log = журнал;
                _subClassLog = subClassLog;
                _config = config;
            }
    
            общедоступная асинхронная задача Run()
            {
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogDebug("Отладка цикла {loopNumber}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogInformation("Информация о цикле {loopNumber}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogWarning("Предупреждение цикла {номер цикла}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogError("Ошибка цикла {loopNumber}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogCritical("Критический цикл {loopNumber}", i);
    
                var subClass = новый подкласс (_subClassLog, _config);
                ждать subClass.AnotherProc();
    
                ждать SubClass.StaticProc ();
            }
        }
    }

SubClass.cs:

    с использованием Microsoft.Extensions.Configuration;
    с помощью Microsoft.Extensions.Logging;
    используя Систему;
    using System.Threading.Tasks;
    
    пространство имен ConsoleApp1
    {
        открытый класс SubClass: ISubClass
        {
            закрытый только для чтения ILogger _log;
            закрытый только для чтения IConfiguration _config;
    
            общедоступный подкласс (журнал ILogger, конфигурация IConfiguration)
            {
                _log = журнал;
                _config = config;
            }
    
            общедоступная асинхронная задача AnotherProc()
            {
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogDebug("Отладка цикла {loopNumber}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogInformation("Информация о цикле {loopNumber}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogWarning("Предупреждение цикла {номер цикла}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogError("Ошибка цикла {loopNumber}", i);
    
                for (int i = 0; i <_config.GetValue ("Цикл"); i++)
                    _log.LogCritical("Критический цикл {loopNumber}", i);
            }
    
            общедоступная статическая асинхронная задача StaticProc()
            {
                var returnBool = true;
    
                пытаться
                {
                    выбросить новое исключение ("");
                }
                улов (исключение ex)
                {
                    returnBool = false;
    
                    // Нет экземпляра, поэтому нет исключения _log.
                    // Как создать автономный ILogger?
                }
    
                return returnBool;
            }
        }
    }

appsettings.json:

    {
      "Петля": 15
    }

log4net.config:

    
    
        
            
            
            
            
            
            
            
                
            
        
        
            
            
            
            
            
            
            
                
            
        
        <корень>
            
            
        
    

1 ответ

Решение

Резюме

Вы также можете ввести ILoggerFactory вместо ILogger:

public TestClass(ILoggerFactory loggerFactory, IConfiguration config)
{
     // create a class logger
     _log = loggerFactory.CreateLogger<TestClass>();

     // and whenever you need a new instance of a special class logger use this:
     _subClassLog = loggerFactory.Create<SubTestClass>();
     _config = config;
}

Но имейте в виду, что это создает новый экземпляр ILogger. Вход в asp net core В вашем случае, если вам действительно нужен статический метод с регистратором, создайте его, только если он уже существует:

private static readonly ILogger<SubClass> _log;
private readonly IConfiguration _config;

public SubClass(ILoggerFactory loggerFactory, IConfiguration config)
{
     _log = _log ??= loggerFactory.CreateLogger<SubClass>();
     _config = config;
}

Но я предпочту или лучше посоветую вам сделать это без статики и просто зарегистрировать службу как синглтон.

Пример 1

Я добавил здесь полный пример: dotnet fiddle Example 1 Также с рабочим DI для консольных приложений, как указано в комментариях.

Пример 2

Имо, вы должны использовать его не со статическими методами. Просто взгляните на мой второй пример здесь dotnet fiddle Пример 2

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