.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 ILoggerFactoryau 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