我应该如何实施 Nlog 记录器以减少 copy/paste 乏味?

How should I implement Nlog logger to reduce copy/paste tedium?

我正在开发一个包含 MVCWeb API 控制器的 .NET 解决方案。在承认我应该比自己的日志记录解决方案更好并且可以从日志记录框架中的某些功能中受益后,我选择了 NLog

我一直在寻找有关如何最好地将 NLog 添加到此解决方案的建议。对于初学者来说,让我们面对现实吧,在每个 class 中放置 static Logger logger = LogManager.GetCurrentClassLogger(); 有点重复。

到目前为止,我找到了两个解决方案:我的控制器继承自包含上述一行代码的基 class 或实现一个空接口并使用 here 中提到的扩展方法。

如何让所有控制器(MVCWeb API)都可以使用记录器以及当前的架构实践告诉我应该做什么?

还有一些其他解决方案,但这取决于它是在 .NET Core 上还是例如净 4.5

my controllers inherit from a base class containing the aforementioned one line

建议这将是一个方法而不是变量,否则记录器名称对于所有控制器都是相同的。

implement an empty interface and use an extension method

您可以在 Controller class 上编写 c# 扩展。这不适用于 ASP.NET 核心,因为控制器是 POCO

另一种选择是使用 Anotar.NLog.Fody:

他们的例子非常自我描述:

您的代码

public class MyClass
{
    void MyMethod()
    { 
        if (LogTo.IsDebugEnabled)
        {
            LogTo.Debug("TheMessage");
        }
    }
}

编译的内容

public class MyClass
{
    static Logger logger = LogManager.GetLogger("MyClass");

    void MyMethod()
    {
        if (logger.IsDebugEnabled)
        {
            logger.Debug("Method: 'Void MyMethod()'. Line: ~12. TheMessage");
        }
    }
}

Fody 是 not ready yet for .NET Core

我个人使用的是 Resharper 宏

看起来是这样MS suggests exactly what you're trying to avoid:

public static class ApplicationLogging
{
    public static ILoggerFactory LoggerFactory {get;} = new LoggerFactory();
    public static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();
}

public class Controller
{
    ILogger Logger { get; } = ApplicationLogging.CreateLogger<Controller>();
}

The result, therefore, is an ILogger property on each class for which you wish to support logging

您可以通过某种基于约定的开发技术来添加这样的 属性,例如,创建一个 PostSharp aspect for a whole assembly, which will find all needed classes in it and assign a logger for it. You may even create that property on fly with Reflection.Emit.PropertyBuilder