将ILogger或ILoggerFactory传递给AspNet Core中的构造函数?

时间:2017-09-02 12:25:37

标签: c# logging dependency-injection asp.net-core

MS文档文章"Introduction to Logging in ASP.NET Core"提供了2个构造函数注入示例

  • 使用 ILogger

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

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

我的问题是我应该传递给从我的控制器调用的

  • ILoggerFactory 传递给从控制器调用的子类 在每个班级电话中 LoggerFactoryExtensions.CreateLogger<MyChildClass>()

  • 将父控制器的 ILogger<MyController> 传递给每个子类 从控制器创建并具有非通用参数ILogger。

在日志中,我更喜欢为每个类看到单独的类别“MyChildClass”,而不是所有类都使用父控制器中的“MyController”类别。 但是,每个对象构造中的CreateLogger可能是一项昂贵的操作(例如,请参阅https://github.com/aspnet/Logging/issues/524

您会推荐哪个选项?你能建议其他方法吗?

1 个答案:

答案 0 :(得分:11)

这更像是一个设计问题。

控制器无论如何都不应该创建子类。这不是控制器应该处理的问题,而是违反SRP(单一责任原则)。

  

我的问题是我应该传递给从我的控制器调用的子类

如果您希望将记录器分开,那么这里没有任何其他选择,只能让子(依赖)类具有自己的记录器。

让子类注入自己的记录器

public class TodoRepository : ITodoRepository {
    private readonly ILogger logger; 

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

    //...
}

然后将子类注入控制器。

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;
    }

    //...
}

这样,当子类被解析并注入控制器时,子记录器将得到解决。