【问题标题】:Pass ILogger or ILoggerFactory to constructors in AspNet Core?将 ILogger 或 ILoggerFactory 传递给 AspNet Core 中的构造函数?
【发布时间】:2018-02-11 07:36:34
【问题描述】:

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

我的问题是我应该将什么传递给从我的控制器调用的 child 类

  • 将 ILoggerFactory 传递给从控制器调用的子类,然后 在每个班级电话中 LoggerFactoryExtensions.CreateLogger&lt;MyChildClass&gt;() 或

  • 将父控制器的 ILogger&lt;MyController&gt; 传递给每个子类 从控制器创建并具有非泛型参数 ILogger。

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

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

【问题讨论】:

  • 让子类注入自己的记录器,然后将子类注入控制器。这样子记录器将在子类被解析并注入控制器时得到解析。
  • 我想说注入ILogger&lt;T&gt; 和ILoggerFactory 都是不好的方法。注入ILoggerFactory 会使你的构造函数变为do too much,而ILogger&lt;T&gt; 只会给你的代码增加更多噪音。相反,您应该注入一个非通用的ILogger,并让 DI 基础设施自动为您注入正确的记录器。然而,MS 文档没有显示这一点的原因是内置容器太有限了。它不能那样为你注入ILogger。
  • @Steven:更高级的依赖注入库是否能够将具有当前类名称的类别的记录器传递给非泛型 ILogger 参数?或者我需要在每个构造函数中插入类别名称?
  • 我认为所有流行的 DI 库都支持这个。
  • @steven,为了记录asp.net内部的东西-需要使用Microsoft.Extendions.DependencyInjection注册一个记录器-比如说Serilog-然后需要插入-比如说-autofac(简单),然后注册在 autofac 中再次使用 Serilog?

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


【解决方案1】:

这更像是一个设计问题。

无论如何,控制器不应该创建子类。这不是控制器应该处理的问题,并且违反了 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;
    }

    //...
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 2014-03-07
    • 2011-09-24
    • 2012-01-15
    • 1970-01-01
    相关资源
    最近更新 更多