Je me connecte très bien en utilisant l'injection de dépendances sur mes contrôleurs, maintenant je dois enregistrer quelque chose from une classe statique.
Comment puis-je me connecter from une classe statique?
Je ne peux pas utiliser l'injection de dépendances car il est statique et je ne peux pas simplement passer un objet de journalisation existant à la classe statique car il aurait le mauvais nom de classe dans le fichier journal.
En d'autres termes, comment puis-je obtenir un enregistreur de la loggerfactory à l'intérieur de ma classe statique?
Je suis tombé sur une question similaire et ils ont pointé un article sur une usine de journalisation dans une classe statique, mais cela ne fonctionne pas vraiment car je ne peux pas en obtenir un nouveau car il n'acceptera pas une classe statique comme paramètre:
"Les types statiques ne peuvent pas être utilisés comme arguments de type"
La solution consiste à avoir une référence statique à LoggerFactory dans une classe statique d'utilitaire initialisée au démarrage:
/// <summary>
/// Shared logger
/// </summary>
internal static class ApplicationLogging
{
internal static ILoggerFactory LoggerFactory { get; set; }// = new LoggerFactory();
internal static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();
internal static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName);
}
Que vous initialisez sur Startup.cs:
public Startup(ILogger<Startup> logger, ILoggerFactory logFactory, IHostingEnvironment hostingEnvironment)
{
_log = logger;
_hostingEnvironment = hostingEnvironment;
Util.ApplicationLogging.LoggerFactory = logFactory;//<===HERE
}
Ensuite, vous pouvez créer un enregistreur à utiliser à partir de votre classe statique comme suit:
internal static class CoreJobSweeper
{
private static ILogger log = Util.ApplicationLogging.CreateLogger("CoreJobSweeper");
Vous pouvez utiliser l'instance statique LoggerFactory
avec la méthode d'extension suivante qui accepte un paramètre régulier de type Type
, plutôt qu'un paramètre de type générique: CreateLogger (ILoggerFactory, Type) =
c'est-à-dire loggerFactory.CreateLogger(typeof(T))
plutôt que loggerFactory.CreateLogger<T>()
Tout d'abord, je suis d'accord avec NightOwl888 réponse.
Mais en option (considérez cela comme une solution de contournement), vous pouvez injecter la dépendance ILogger
via le paramètre de méthode => donc une classe qui appellera cette méthode statique devrait être chargée de fournir une implémentation correcte de ILogger
.
static class YourClass
{
public static void DoSomething(ILogger logger)
{
// do something
// call log.Log();
}
}
Comment puis-je me connecter à partir d'une classe statique?
Non.
Si vous faites quelque chose d'assez important pour être connecté, cela devrait être dans un service. Ensuite, vous pouvez vous connecter en injectant l'enregistreur via le constructeur.
Les classes et méthodes statiques sont utiles, mais devraient être réservées à une logique simple qui ne changera probablement pas et qui est garantie de ne jamais avoir besoin de dépendances. Si vous devez poser cette question, vous avez clairement franchi cette ligne.
Une question plus utile est: Pourquoi la classe est-elle statique?
Le conteneur DI dans .NET Core (ainsi que tous les autres que j'ai vus) a un style de vie singleton qui agit de la même manière qu'une classe statique ( une instance pour l’ensemble de l’application). Il vous suffit d'enregistrer le service en conséquence et le conteneur DI s'occupe du reste:
services.AddSingleton<IMyService, MyService>();
Cela élimine le besoin de rendre statique l'un de vos services. Sans oublier que vous pouvez y injecter des dépendances, comme lorsque vous avez besoin d'un enregistreur.
Les méthodes d'extension sont très utiles, mais je ne recommanderais pas de les utiliser pour tout type de logique métier. Cependant, les assistants HTML sont implémentés à l'aide de méthodes d'extension, donc si vous devez utiliser DI avec eux, il y a un problème. Dans ASP.NET Core, il est désormais possible (et recommandé) de rendre la DI conviviale afficher les composants plutôt que les méthodes d'extension lorsque vous avez besoin de dépendances.
Mais si vous avez un de ces problèmes où vous voulez absolument que ce soit une méthode d'extension, aucune question n'est posée. Il est possible d'utiliser cette technique pour utiliser DI avec des méthodes d'extension. Je ne recommanderais pas de le faire partout, mais dans les cas où vous n'avez pas le choix (comme avec MVC 5), cela fonctionnera. Veillez cependant à ce que seule la méthode d'extension soit statique.