在net-core2.0中使用NLog进行DI

时间:2019-04-04 06:28:50

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

我对Net Core 2.0上的NLog有点了解 我想在控制台应用程序中使用构造函数创建一个类。

Bot.cs

public class Bot : IBot
{
    static TelegramBotClient _botClient;
    Microsoft.Extensions.Logging.ILogger<Bot> _logger;

    public Bot(string botToken, WebProxy httpProxy, ILogger<Bot> logger)
    {
        _logger = logger;
        _botClient = new TelegramBotClient(botToken, httpProxy);
        //...
    }
}

和Program.cs

public static async Task Main(string[] args)
{
     //...

    appModel = configuration.GetSection("ApplicationModel").Get<ApplicationModel>();
    var userName = appModel.ProxyConfiguration.UserName;
    var password = appModel.ProxyConfiguration.Password;

    var httpProxy = new WebProxy(appModel.ProxyConfiguration.Url, appModel.ProxyConfiguration.Port)
    {
        Credentials = credentials
    };
    NLog.ILogger Logger = LogManager.GetCurrentClassLogger();
    _botClient = new Bot(appModel.BotConfiguration.BotToken, httpProxy, ???);

    //...
}

我该怎么做才能使Microsoft.Extensions.Logging.ILogger<Bot>类中的Bot?在程序类中,我只有NLog.ILogger。 “部分” DI的最佳实践是什么?我想将字符串botToken,WebProxy httpProxy传递给Bot类中的构造函数,但希望ILogger<Bot>记录器自动解决。

有可能吗?

我有一个想法将IOptions<ApplicationMode> appSettings传递给Bot类,但这将是一个肮脏的代码,不是吗?

1 个答案:

答案 0 :(得分:1)

NLog.ILogger Logger = LogManager.GetCurrentClassLogger();

返回类型为NLog.Logger的对象。

另一方面,您的类期望使用Microsoft.Extensions.Logging.ILogger<Bot>类型的构造函数参数。因此,尽管两者都被命名为ILogger,但它们实际上是完全不同的类型。

一个答案是将您的班级改为期望NLog.Logger而不是Microsoft.Extensions.Logging.ILogger<Bot>。然后,您可以这样做:

NLog.ILogger logger = LogManager.GetCurrentClassLogger();
_botClient = new Bot(appModel.BotConfiguration.BotToken, httpProxy, logger);

那可能行得通。我唯一关心的是,它使您的Bot类依赖于NLog。现在,它依赖于框架抽象,这更好,因为它意味着您可以使用NLog或替代某些其他记录器。

因此,要保持现状,您需要创建一个使NLog.ILogger适应Microsoft.Extensions.Logging.ILogger<Bot>的类。

(到这一点,我开始自己编写适配器。那时我几乎肯定已经存在该适配器。)

幸运的是,NLog已经在NLog.Extensions.Logging中完成了此操作,您可以将其添加为NuGet软件包。他们提供此功能是完全合理的,因为并非每个想要使用NLog的人都希望将NLog特定的类型放在每个需要记录器的类中。

他们provide documentation介绍如何在控制台应用程序中进行配置。


我从这里开始:

public class NLogger : ILogger
{
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        throw new NotImplementedException();
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        throw new NotImplementedException();
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        throw new NotImplementedException();
    }
}

...并想知道实现会是什么样子。事实证明,它看起来像这样:https://github.com/NLog/NLog.Extensions.Logging/blob/master/src/NLog.Extensions.Logging/Logging/NLogLogger.cs

如果我以为我要提出这个建议,那我就错了。