【问题标题】:How to get access to Logger object in a downstream object?如何访问下游对象中的 Logger 对象?
【发布时间】:2019-04-24 03:10:43
【问题描述】:

考虑 .NET Core Web 项目的以下项目结构。

MyApp.UI 项目 (MVC) 调用 MyApp.BusinessRules 调用 MyApp.ServiceLayer 调用 MyApp.DbAccess 项目调用任何东西。

在前端项目(MyApp.UI)中,我定义了logger。我想访问 MyApp.DbAccess 项目(或任何下游项目)中 logger 的这个实例,而无需通过控制器操作的参数传递它。我也无法在结构中进行那么深的依赖注入。

那么如何访问记录器呢?

【问题讨论】:

  • logger 应该定义在比 UI 更低的项目中,否则你所有的其他层都直接或间接地依赖于 UI 层,这是不理想的。您可以创建另一个库,例如 MyApp.Common,然后将记录器移到那里。
  • 什么是“logger”?它是您自己创造的,还是您使用Microsoft.Extensions.Logging 门面?
  • @ChrisPratt 是的,基本上是 Microsoft.Extensions.Logging 记录器工厂。特别是 Serilog 作为提供者。
  • 为什么不能对数据库访问逻辑使用依赖注入?如果您将 ILogger<T> 注入 db 服务的构造函数(即使它是单例),那么记录器将负责记录范围 - ASP.NET Core 将为每个请求设置一个记录范围。
  • @Sam 这就是我最终所做的。到目前为止效果很好。

标签: c# asp.net-core .net-core


【解决方案1】:

不应在 UI 层中定义记录器。这是一个横切关注点,因此您应该在外部库中定义它,并在您需要记录的所有项目中引用它。

如果您只想记录异常,您可以定义一个全局异常处理程序,让异常冒泡到 UI 层并在那里记录它们。示例here

如果您真的想一直向下传递 Logger,您可以使用 Action 作为方法中的参数,并使用您希望在下游调用的方法调用传递一个 lambda。

    public class Logger
    {
        public string Message { get; set; }

        public void Log(string message)
        {
            Message = message;
        }
    }

    public class Business
    {
        public void DoWork(int id, Action<string> logAction)
        {
            if (id < 0)
            {
                logAction("The string is less than zero");
            }
        }
    }

调用代码

Logger logger = new Logger();
Business business = new Business();

business.DoWork(-1, (message) => logger.Log(message));

【讨论】:

  • 记录器在 Startup.cs 中定义并绑定到 WebHost。它不仅用于处理异常,还用于跟踪。
  • @AngryHacker 刚刚更新了我的答案 - 您可以定义一个 lambda 并将其传递给您的下游方法:Action&lt;string&gt; loggingAction = (message) =&gt; logger.Log(message);
  • 那么DoWork的参数列表是什么?是 (int, Func) 吗?
  • 在我的例子中,这是签名void DoWork(int id, Action&lt;string&gt; logAction) - 它有一个int和用于记录的lambda
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 2016-06-13
  • 2017-12-29
相关资源
最近更新 更多