.NET Core DI и подклассы
Здесь вы новичок в.NET Core. Я искал другую документацию, ветку или руководство, которое отвечает на мои вопросы, но не могу найти его. Если вы думаете, что да, укажите на это.
Я пытаюсь создать простое консольное приложение.NET 5 с DI и буквально застреваю на структурировании классов с ведением журнала.
Это правильный способ передать регистратор (или любую другую службу) в подкласс с помощью DI в.NET Core? Согласно приведенному ниже коду, в моем конструкторе родительского класса я беру дополнительный ILogger для каждого подкласса, например.
ILogger<SubClass>
?public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)
Как мне инициализировать регистратор в моем статическом процессе
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