【问题标题】:ASP.NET 5 Best practice to log exceptions in layersASP.NET 5 分层记录异常的最佳实践
【发布时间】:2016-02-22 13:46:34
【问题描述】:

我有一个使用 ASP.NET 5 和 MVC 6 的项目。我有几个层:

  • 我的表示层
  • 我的领域模型层
  • 我的基础设施层
  • 我的业务逻辑层
  • 还有我的数据访问层。

目前,我使用依赖注入在我的控制器方法中记录异常。

private readonly ILogger<CustomerController> _logger;
public CustomerController(ILogger<CustomerController> logger)
{
     _logger = logger;
}

public bool TestLog()
{
     _logger.LogError((int)LoggingEvents.LIST_ITEMS, "Test info #543434");
     return true;
}

在我的其他层(例如我的数据访问层)中使用记录器的最佳做法是什么?

【问题讨论】:

    标签: exception-handling asp.net-core asp.net-core-mvc serilog


    【解决方案1】:

    最好只在您的应用程序层(控制器、应用程序服务 - 但不是域服务)中使用ILogger&lt;T&gt;

    如果您想为您的域服务/存储库添加日志记录,最好为其创建装饰器。这只有在你从它们的实现中抽象出你的接口并在任何地方使用/注入接口时才有效)。

    但是,使用装饰器可以做的事情是有限制的。您可以在调用公共接口中定义的方法之前和之后记录。不在通话中。

    为什么要避免将记录器记录/注入到服务中?

    耦合

    您应该避免在域对象中注入 ILogger&lt;T&gt;,因为这会将您的域与 ASP.NET Core 日志记录框架/基类耦合。但是,您始终可以定义自己的记录器接口以在您的域中使用它并将其实现为 ILogger&lt;T&gt; 的包装器。

    SOLID原理

    SOLID原则中的

    S代表SRP(Single Responsibility Principle),并表示,一个对象应该只有一个责任。将日志记录和持久性或业务逻辑放入一个对象中违反了这一原则。

    但最终,您必须权衡开发成本和从中获得的收益。如果它是一个长期存在的应用程序(将在未来 10 年左右使用)并且是一个复杂的应用程序,那么将日志记录为装饰器肯定是有意义的。如果它是一个只有几周开发时间的小项目,那么这种抽象的好处可能不会超过成本。

    【讨论】:

    • “因为这将您的域耦合到 ASP.NET Core 日志框架/基类” – ASP.NET Core 中包含的 ILogger 接口已经非常通用并且对其他人开放实施;这里真的没有太多的耦合。它也在 Extensions 命名空间中(不是 ASP.NET),所以它是一个单独的实体,实际上被认为是直接适配到 .NET Core 中。
    • @poke:是的,但是如果界面要更改,它会破坏您的整个域。当您拥有自己的界面时,只有在您修改它时才会中断。如果 .NET Core 记录器接口发生更改,则只有围绕它的包装器/提供者会失败,这不是问题,因为它是基础架构并且在您的域之外。但由公司/开发人员决定由谁来推动抽象:P
    【解决方案2】:

    “最佳实践”是为每个组件注入自己的记录器,并让每个组件进行自己的日志记录。

    如果您认为这对您的应用程序来说过于嘈杂,那么您可以更改命名空间部分的详细级别,这样您只会得到例如Information 级别日志用于您的控制器,Warning(或更糟)用于其他所有内容:

    loggerFactory.AddConsole(new ConsoleLoggerSettings()
    {
        Switches = new Dictionary<string, LogLevel>()
        {
            ["MyNamespace.Services"] = LogLevel.Warning,
            ["MyNamsepace.Controllers"] = LogLevel.Information
        }
    });
    

    【讨论】:

    • 赞成 - 不知道为什么有人反对这个?我认为它可能会改进答案,提到它假设依赖注入也将在其他层中使用。
    【解决方案3】:

    如果您想记录未处理的异常,您可能应该添加一个可以处理该问题的中间件。您可以在这个 SO 答案中看到一个示例:https://stackoverflow.com/a/31054664/5795

    【讨论】:

      猜你喜欢
      • 2017-11-15
      • 2018-08-08
      • 2011-05-10
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多