web-dev-qa-db-fra.com

Passer ILogger ou ILoggerFactory aux constructeurs dans AspNet Core?

L'article MS docs "Introduction to Logging in ASP.NET Core" donne 2 exemples d'injection de constructeur

  • en utilisant ILogger

    private readonly ILogger _logger;   
    public TodoController(ILogger<TodoController> logger)  
    { 
        _logger = logger;   
    }
    
  • et ILoggerFactory

    private readonly ILogger _logger;  
    public TodoController( ILoggerFactory loggerFactory)  
    {  
        _logger = loggerFactory.CreateLogger<TodoController>();  
    }
    

Ma question est ce que dois-je passer aux classes enfants appelées depuis mon contrôleur

  • passez ILoggerFactory à mes classes enfants appelées depuis le contrôleur et dans chaque classe appelez LoggerFactoryExtensions.CreateLogger<MyChildClass>() ou

  • passez le contrôleur parent ILogger<MyController> à chaque classe enfant créée à partir du contrôleur et ayant un paramètre ILogger non générique.

Dans les journaux, je préfère voir une catégorie distincte "MyChildClass" pour chaque classe, plutôt que toutes les classes utilisent la catégorie "MyController" du contrôleur parent.
Cependant, CreateLogger dans chaque construction d'objet peut être une opération coûteuse (par exemple, voir https://github.com/aspnet/Logging/issues/524 )

Quelle option recommanderez-vous? Pouvez-vous suggérer une autre approche?

20
Michael Freidgeim

Il s'agit davantage d'un problème de conception.

De toute façon, le contrôleur ne doit pas créer de classes enfants. Ce n'est pas une préoccupation que le responsable du traitement doit traiter et va à l'encontre du SRP (principe de responsabilité unique).

Ma question est ce que dois-je passer aux classes enfants appelées depuis mon contrôleur

Si vous préférez séparer les enregistreurs, il n'y a vraiment pas d'autre choix ici que d'avoir des classes enfants (dépendantes) ayant leurs propres enregistreurs.

Demandez aux classes enfants d'injecter leur propre enregistreur

public class TodoRepository : ITodoRepository {
    private readonly ILogger logger; 

    public TodoRepository(ILogger<TodoRepository> logger) { 
        this.logger = logger;   
    }

    //...
}

puis injectez la classe enfant dans le contrôleur.

public class TodoController : Controller {
    private readonly ILogger logger;
    private readonly ITodoRepository todoRepository;

    public TodoController(ILogger<TodoController> logger, ITodoRepository todoRepository) {
        this.logger = logger;   
        this.todoRepository = todoRepository;
    }

    //...
}

De cette façon, les enregistreurs enfants seront résolus lorsque les classes enfants seront résolues et injectées dans le contrôleur.

12
Nkosi