.NET Core DI et sous-classes
Nouveau sur .NET Core ici. J'ai recherché une autre documentation, un fil de discussion ou un guide qui répond à mes questions mais je n'en trouve pas, si vous pensez que c'est le cas, veuillez le signaler.
J'essaie de créer une simple application console .NET 5 avec DI et je reste littéralement coincé dans la structuration des classes avec la journalisation.
Est-ce la bonne façon de passer un enregistreur (ou tout autre service) à une sous-classe à l'aide de DI dans .NET Core? Selon le code ci-dessous, dans mon constructeur de classe parent, je prends un ILogger supplémentaire pour chaque sous-classe, par exemple.
ILogger<SubClass>
?public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)
Comment initialiser un enregistreur dans mon proc statique
StaticProc
?public static async Task<bool> StaticProc()
Program.cs:
en utilisant Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; en utilisant Microsoft.Extensions.Hosting; en utilisant Microsoft.Extensions.Logging; en utilisant le système; en utilisant System.IO; using System.Threading.Tasks; espace de noms ConsoleApp1 { programme de classe { Tâche principale statique asynchrone (string [] args) { var builder = nouveau ConfigurationBuilder (); BuildConfig (constructeur); var hôte = Host.CreateDefaultBuilder () .ConfigureServices ((contexte, services) => { services.AddTransient <ITestClass, TestClass> (); services.AddTransient <ISubClass, SubClass> (); }) .ConfigureLogging (logBuilder => { logBuilder.SetMinimumLevel (LogLevel.Trace); logBuilder.AddLog4Net ("log4net.config"); }) .Construire(); var log = host.Services.GetService <ILoggerFactory> () .CreateLogger <Programme> (); log.LogInformation ($"Application Started"); var svc = ActivatorUtilities.CreateInstance<TestClass>(host.Services); await svc.Run(); log.LogInformation($«Application terminée»); } static void BuildConfig (générateur IConfigurationBuilder) { builder.SetBasePath (Directory.GetCurrentDirectory ()) .AddJsonFile ("appsettings.json", facultatif: false, reloadOnChange: true) .AddJsonFile ($ "appsettings. {Environment.GetEnvironmentVariable (" ASPNETCORE_ENVIRONMENT ") ??" Development "}. Json", optionnel: true) .AddEnvironmentVariables (); } } }
TestClass.cs:
en utilisant Microsoft.Extensions.Configuration; en utilisant Microsoft.Extensions.Logging; using System.Threading.Tasks; espace de noms ConsoleApp1 { classe publique TestClass: ITestClass { privé en lecture seule ILogger <TestClass> _log; private readonly ILogger <SubClass> _subClassLog; privé en lecture seule IConfiguration _config; public TestClass (journal ILogger <TestClass>, ILogger <SubClass> subClassLog, configuration IConfiguration) { _log = journal; _subClassLog = subClassLog; _config = config; } exécution de la tâche publique async () { for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogDebug ("Débogage de boucle {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogInformation ("Informations sur la boucle {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogWarning ("Loop warn {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogError ("Erreur de boucle {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogCritical ("Boucle critique {loopNumber}", i); var subClass = new SubClass (_subClassLog, _config); attendre subClass.AnotherProc (); attendre SubClass.StaticProc (); } } }
SubClass.cs:
en utilisant Microsoft.Extensions.Configuration; en utilisant Microsoft.Extensions.Logging; en utilisant le système; using System.Threading.Tasks; espace de noms ConsoleApp1 { classe publique SubClass: ISubClass { privé en lecture seule ILogger <SubClass> _log; privé en lecture seule IConfiguration _config; public SubClass (journal ILogger <SubClass>, configuration IConfiguration) { _log = journal; _config = config; } public async Tâche AnotherProc () { for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogDebug ("Débogage de boucle {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogInformation ("Informations sur la boucle {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogWarning ("Loop warn {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogError ("Erreur de boucle {loopNumber}", i); for (int i = 0; i <_config.GetValue <int> ("Boucle"); i ++) _log.LogCritical ("Boucle critique {loopNumber}", i); } Tâche publique statique async <bool> StaticProc () { var returnBool = true; essayer { lancer une nouvelle exception (""); } catch (Exception ex) { returnBool = false; // Pas d'instance, donc pas d'exception _log. // Comment créer un ILogger autonome? } return returnBool; } } }
appsettings.json:
{ "Boucle": 15 }
log4net.config:
<? xml version = "1.0" encoding = "utf-8"?> <log4net> <appender name = "Info" type = "log4net.Appender.RollingFileAppender"> <seuil value = "DEBUG" /> <param name = "File" value = "App_Data \\ Log \\ Info.log" /> <param name = "AppendToFile" value = "true" /> <maximumFileSize value = "5120 Ko" /> <lockModel type = "log4net.Appender.FileAppender + MinimalLock" /> <maxSizeRollBackups value = "1000" /> <layout type = "log4net.Layout.PatternLayout"> <conversionPattern value = "% d {aaaa-MM-jj HH: mm: ss} - [% t]% -5p% c% x -% m% n" /> </layout> </appender> <appender name = "Error" type = "log4net.Appender.RollingFileAppender"> <seuil valeur = "Erreur" /> <param name = "File" value = "App_Data \\ Log \\ Error.log" /> <param name = "AppendToFile" value = "true" /> <maximumFileSize value = "5120 Ko" /> <lockModel type = "log4net.Appender.FileAppender + MinimalLock" /> <maxSizeRollBackups value = "1000" /> <layout type = "log4net.Layout.PatternLayout"> <conversionPattern value = "% d {aaaa-MM-jj HH: mm: ss} - [% t]% -5p% c% x -% m% n" /> </layout> </appender> <racine> <appender-ref ref = "Info" /> <appender-ref ref = "Erreur" /> </root> </log4net>
Réponses
Sommaire
Vous pouvez également injecter un ILoggerFactory
au lieu de 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;
}
Mais sachez que cela crée une nouvelle instance de ILogger. Connexion asp net core Dans votre cas, si vous avez vraiment besoin de la méthode statique avec un enregistreur, créez-la uniquement si elle existe déjà:
private static readonly ILogger<SubClass> _log;
private readonly IConfiguration _config;
public SubClass(ILoggerFactory loggerFactory, IConfiguration config)
{
_log = _log ??= loggerFactory.CreateLogger<SubClass>();
_config = config;
}
Mais je préfère ou mieux vous conseiller de le faire sans avoir de statique et d'enregistrer simplement le service en tant que singleton.
Exemple 1
J'ai ajouté un exemple complet ici: dotnet fiddle Exemple 1 Également avec la DI de travail pour les applications de console comme mentionné dans les commentaires.
Exemple 2
Imo, vous ne devriez pas l'utiliser avec des méthodes statiques. Regardez simplement mon deuxième exemple ici dotnet fiddle Exemple 2