扩展类/方法功能的正确方法 - 使用NLog作为示例

时间:2017-07-25 19:05:14

标签: c# .net oop nlog extend

我在这里使用NLog .NET日志库作为示例;我的问题不是NLog特有的。

典型的NLog日志记录如下所示:

private static Logger log = LogManager.GetLogger("logger_name");
log.Info("Some log message");

我想为Info()方法添加功能。也许我想在日志消息中添加一些时间戳。

我完成的方式绝对是可怕的,只是臭味的代码。

我创建了一个包含Logger实例的辅助类,实现了它自己的(但命名相同)GetLogger()Info()方法(呃,很糟糕),然后包含一些Info()中的自定义功能。

public static class NLogLogManagerHelper // Can't derive from LogManager because it's sealed
{
    public static string _loggerName;
    public static NLog.Logger _log;

    public static NLog.Logger GetLogger(string loggerName)
    {
        _loggerName = loggerName;
        _log = LogManager.GetLogger(loggerName);
        return _log;
    }

    public static void Info(string message)
    {
        var eventInfo = new LogEventInfo(LogLevel.Info, _loggerName, message);
        // Add some custom functionality
        eventInfo.Properties["mytimestamp"] = Time.ConvertUtcToEst(DateTime.UtcNow);
        _log.Log(eventInfo);
    }
}

我甚至不确定采用辅助工具和包装Logger的方法是正确的方法。

这“有效”,但是很臭。一个很大的问题是,NLog的Logger类具有Info()方法,所以我可以创建一个继承自MyLogger的{​​{1}},但是我无法实现{ {1}}因为它不可覆盖。另一个问题是,由于我复制了Info()方法,因此无法访问任何重载。我想知道解决这个问题的正确方法,无论是OO方法,还是设计模式,还是其他什么。

1 个答案:

答案 0 :(得分:2)

至少有一个明确的代码气味,即调用sysconf(_SC_CLK_TCK)方法使用不同的GetLogger()值会覆盖 loggerName和{{ 1}}(顺便说一句,这也应该是私有的),这意味着在这种情况下你不能以可靠的方式随后调用你的static string _loggerName方法。

您最好在您创建常规方式的static NLog.Logger _log实例上使用扩展方法。扩展方法是使它看起来像是在扩展类的一种很好的方式,即使实际上你不能,同时也不必提及静态类(只需添加一个Info() - 行它的名称空间)。

NLog.Logger