.NET Core DI und Unterklassen
Neu bei .NET Core hier. Ich habe nach einer anderen Dokumentation, einem anderen Thread oder einer anderen Anleitung gesucht, die meine Fragen beantwortet, aber keine finden kann. Wenn Sie glauben, dass dies der Fall ist, weisen Sie darauf hin.
Ich versuche, eine einfache .NET 5-Konsolen-App mit DI zu erstellen und stecke buchstäblich in der Strukturierung von Klassen mit Protokollierung fest.
Ist dies der richtige Weg, um einen Logger (oder einen anderen Dienst) mit DI in .NET Core an eine Unterklasse zu übergeben? Gemäß dem folgenden Code nehme ich in meinem übergeordneten Klassenkonstruktor einen zusätzlichen ILogger für jede Unterklasse, z.
ILogger<SubClass>
?public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)
Wie würde ich einen Logger in meinem statischen Prozess initialisieren
StaticProc
?public static async Task<bool> StaticProc()
Program.cs:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.IO; using System.Threading.Tasks; Namespace ConsoleApp1 { Klassenprogramm { statische asynchrone Aufgabe Main (string [] args) { var builder = new ConfigurationBuilder (); BuildConfig (Builder); var host = Host.CreateDefaultBuilder () .ConfigureServices ((Kontext, Dienste) => { services.AddTransient <ITestClass, TestClass> (); services.AddTransient <ISubClass, SubClass> (); }) .ConfigureLogging (logBuilder => { logBuilder.SetMinimumLevel (LogLevel.Trace); logBuilder.AddLog4Net ("log4net.config"); }) .Bauen(); var log = host.Services.GetService <ILoggerFactory> () .CreateLogger <Programm> (); log.LogInformation ($"Application Started"); var svc = ActivatorUtilities.CreateInstance<TestClass>(host.Services); await svc.Run(); log.LogInformation($"Bewerbung beendet"); }} statische Leere BuildConfig (Builder für IConfigurationBuilder) { builder.SetBasePath (Directory.GetCurrentDirectory ()) .AddJsonFile ("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile ($ "appsettings. {Environment.GetEnvironmentVariable (" ASPNETCORE_ENVIRONMENT ") ??" Development "}. Json", optional: true) .AddEnvironmentVariables (); }} }} }}
TestClass.cs:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System.Threading.Tasks; Namespace ConsoleApp1 { öffentliche Klasse TestClass: ITestClass { privat schreibgeschützt ILogger <Testklasse> _log; privat schreibgeschützt ILogger <SubClass> _subClassLog; privat schreibgeschützt IConfiguration _config; public TestClass (ILogger <TestClass> -Protokoll, ILogger <SubClass> subClassLog, IConfiguration config) { _log = log; _subClassLog = subClassLog; _config = config; }} public async Task Run () { for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogDebug ("Loop debug {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogInformation ("Loop info {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogWarning ("Loop warn {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogError ("Schleifenfehler {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogCritical ("Schleife kritisch {loopNumber}", i); var subClass = neue Unterklasse (_subClassLog, _config); warte auf subClass.AnotherProc (); warte auf SubClass.StaticProc (); }} }} }}
SubClass.cs:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; Namespace ConsoleApp1 { öffentliche Klasse SubClass: ISubClass { privat schreibgeschützt ILogger <SubClass> _log; privat schreibgeschützt IConfiguration _config; öffentliche Unterklasse (ILogger <SubClass> -Protokoll, IConfiguration-Konfiguration) { _log = log; _config = config; }} öffentliche asynchrone Aufgabe AnotherProc () { for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogDebug ("Loop debug {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogInformation ("Loop info {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogWarning ("Loop warn {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogError ("Schleifenfehler {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Schleife"); i ++) _log.LogCritical ("Schleife kritisch {loopNumber}", i); }} public static async Task <bool> StaticProc () { var returnBool = true; Versuchen { neue Ausnahme auslösen (""); }} fangen (Ausnahme ex) { returnBool = false; // Keine Instanz, also keine _log-Ausnahme. // Wie erstelle ich einen eigenständigen ILogger? }} return returnBool; }} }} }}
appsettings.json:
{ "Schleife": 15 }}
log4net.config:
<? xml version = "1.0" encoding = "utf-8"?> <log4net> <appender name = "Info" type = "log4net.Appender.RollingFileAppender"> <Schwellwert = "DEBUG" /> <param name = "File" value = "App_Data \\ Log \\ Info.log" /> <param name = "AppendToFile" value = "true" /> <maximumFileSize value = "5120KB" /> <lockingModel type = "log4net.Appender.FileAppender + MinimalLock" /> <maxSizeRollBackups value = "1000" /> <layout type = "log4net.Layout.PatternLayout"> <convertPattern value = "% d {JJJJ-MM-TT HH: mm: ss} - [% t]% -5p% c% x -% m% n" /> </ layout> </ kader> <appender name = "Error" type = "log4net.Appender.RollingFileAppender"> <Schwellwert = "Fehler" /> <param name = "File" value = "App_Data \\ Log \\ Error.log" /> <param name = "AppendToFile" value = "true" /> <maximumFileSize value = "5120KB" /> <lockingModel type = "log4net.Appender.FileAppender + MinimalLock" /> <maxSizeRollBackups value = "1000" /> <layout type = "log4net.Layout.PatternLayout"> <convertPattern value = "% d {JJJJ-MM-TT HH: mm: ss} - [% t]% -5p% c% x -% m% n" /> </ layout> </ kader> <wurzel> <appender-ref ref = "Info" /> <appender-ref ref = "Fehler" /> </ root> </ log4net>
Antworten
Zusammenfassung
Sie können auch eine ILoggerFactory
anstelle der 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;
}
Beachten Sie jedoch, dass dadurch eine neue Instanz des ILogger erstellt wird. Anmelden in asp net core Wenn Sie in Ihrem Fall die statische Methode mit einem Logger wirklich benötigen, erstellen Sie sie nur, wenn sie bereits vorhanden ist:
private static readonly ILogger<SubClass> _log;
private readonly IConfiguration _config;
public SubClass(ILoggerFactory loggerFactory, IConfiguration config)
{
_log = _log ??= loggerFactory.CreateLogger<SubClass>();
_config = config;
}
Aber ich werde Ihnen den Vorzug geben oder besser raten, dies ohne Statik zu tun und den Dienst einfach als Singleton zu registrieren.
Beispiel 1
Ich habe hier ein vollständiges Beispiel hinzugefügt: dotnet fiddle Beispiel 1 Auch mit dem funktionierenden DI für Konsolen-Apps, wie in den Kommentaren erwähnt.
Beispiel 2
Imo sollten Sie es nicht mit statischen Methoden verwenden. Schauen Sie sich hier mein zweites Beispiel an. Dotnet Fiddle Beispiel 2